From 728ed3c7791ac775e29e574392de67c97cee502b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 8 Sep 2026 21:19:32 +0000 Subject: [PATCH 1/4] Initial plan From eddd647e1753254cdbf84ae5370351fc7ff9120c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 8 Sep 2026 21:23:52 +0000 Subject: [PATCH 2/4] Fix localized conda named flow Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com> --- src/managers/conda/condaStepBasedFlow.ts | 4 +- .../conda/condaStepBasedFlow.unit.test.ts | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/test/managers/conda/condaStepBasedFlow.unit.test.ts diff --git a/src/managers/conda/condaStepBasedFlow.ts b/src/managers/conda/condaStepBasedFlow.ts index 0a3e50343..b10e15a67 100644 --- a/src/managers/conda/condaStepBasedFlow.ts +++ b/src/managers/conda/condaStepBasedFlow.ts @@ -60,7 +60,7 @@ async function selectEnvironmentType(state: CondaCreationState): Promise 1) { - state.envType = 'Named'; + state.envType = CondaStrings.condaNamed; return selectPythonVersion; } @@ -129,7 +129,7 @@ async function selectPythonVersion(state: CondaCreationState): Promise { + let originalCondaNamed: string; + + setup(() => { + originalCondaNamed = CondaStrings.condaNamed; + Object.defineProperty(CondaStrings, 'condaNamed', { value: '명명됨', configurable: true }); + }); + + teardown(() => { + sinon.restore(); + Object.defineProperty(CondaStrings, 'condaNamed', { value: originalCondaNamed, configurable: true }); + }); + + test('routes a localized Named selection to named environment creation', async () => { + const createdEnvironment = {} as PythonEnvironment; + const showQuickPickStub = sinon.stub(windowApis, 'showQuickPickWithButtons'); + showQuickPickStub.onFirstCall().callsFake(async (items: readonly QuickPickItem[]) => items[0]); + showQuickPickStub.onSecondCall().resolves({ label: 'Python', description: '3.12' } as QuickPickItem); + const showInputBoxStub = sinon.stub(windowApis, 'showInputBoxWithButtons').resolves('localized-env'); + const createNamedStub = sinon.stub(condaUtils, 'createNamedCondaEnvironment').resolves(createdEnvironment); + const createPrefixStub = sinon.stub(condaUtils, 'createPrefixCondaEnvironment'); + const api = { + getEnvironments: sinon.stub().resolves([]), + getPythonProject: sinon.stub().returns(undefined), + } as unknown as PythonEnvironmentApi; + + const result = await createStepBasedCondaFlow( + api, + createMockLogOutputChannel(), + {} as EnvironmentManager, + Uri.file('workspace'), + ); + + assert.strictEqual(result, createdEnvironment); + assert.strictEqual((showQuickPickStub.firstCall.args[0] as QuickPickItem[])[0].label, '명명됨'); + assert.ok(showInputBoxStub.calledOnce); + assert.ok(createNamedStub.calledOnceWithExactly(api, sinon.match.any, sinon.match.any, 'localized-env', '3.12')); + assert.ok(createPrefixStub.notCalled); + }); +}); From 81a5030c15c22af55dcad70f4119822ba2303520 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 8 Sep 2026 21:44:23 +0000 Subject: [PATCH 3/4] Integrate conda step flow test Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com> --- .../condaEnvManager.createRemove.unit.test.ts | 47 ++++++++++++++++- .../conda/condaStepBasedFlow.unit.test.ts | 50 ------------------- 2 files changed, 46 insertions(+), 51 deletions(-) delete mode 100644 src/test/managers/conda/condaStepBasedFlow.unit.test.ts diff --git a/src/test/managers/conda/condaEnvManager.createRemove.unit.test.ts b/src/test/managers/conda/condaEnvManager.createRemove.unit.test.ts index 3c3abdf25..e18eaa289 100644 --- a/src/test/managers/conda/condaEnvManager.createRemove.unit.test.ts +++ b/src/test/managers/conda/condaEnvManager.createRemove.unit.test.ts @@ -4,19 +4,23 @@ import * as fse from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; import * as sinon from 'sinon'; -import { Uri } from 'vscode'; +import { QuickPickItem, Uri } from 'vscode'; import { DidChangeEnvironmentEventArgs, DidChangeEnvironmentsEventArgs, + EnvironmentManager, EnvironmentChangeKind, PythonEnvironment, PythonEnvironmentApi, PythonProject, } from '../../../api'; +import { CondaStrings } from '../../../common/localize'; import * as windowApis from '../../../common/window.apis'; import { NativePythonFinder } from '../../../managers/common/nativePythonFinder'; import { CondaEnvManager } from '../../../managers/conda/condaEnvManager'; +import { createStepBasedCondaFlow } from '../../../managers/conda/condaStepBasedFlow'; import * as condaUtils from '../../../managers/conda/condaUtils'; +import { createMockLogOutputChannel } from '../../mocks/helper'; import { makeMockCondaEnvironment as makeEnv } from '../../mocks/pythonEnvironment'; const TEST_ROOT = Uri.file(path.join(os.tmpdir(), 'vscode-python-envs-tests', 'conda-manager')).fsPath; @@ -46,6 +50,47 @@ function createManager(apiOverrides?: Partial): CondaEnvMa return manager; } +suite('CondaEnvManager.create - step-based flow', () => { + let originalCondaNamed: string; + + setup(() => { + originalCondaNamed = CondaStrings.condaNamed; + Object.defineProperty(CondaStrings, 'condaNamed', { value: '명명됨', configurable: true }); + }); + + teardown(() => { + sinon.restore(); + Object.defineProperty(CondaStrings, 'condaNamed', { value: originalCondaNamed, configurable: true }); + }); + + test('routes a localized Named selection to named environment creation', async () => { + const createdEnvironment = {} as PythonEnvironment; + const showQuickPickStub = sinon.stub(windowApis, 'showQuickPickWithButtons'); + showQuickPickStub.onFirstCall().callsFake(async (items: readonly QuickPickItem[]) => items[0]); + showQuickPickStub.onSecondCall().resolves({ label: 'Python', description: '3.12' } as QuickPickItem); + const showInputBoxStub = sinon.stub(windowApis, 'showInputBoxWithButtons').resolves('localized-env'); + const createNamedStub = sinon.stub(condaUtils, 'createNamedCondaEnvironment').resolves(createdEnvironment); + const createPrefixStub = sinon.stub(condaUtils, 'createPrefixCondaEnvironment'); + const api = { + getEnvironments: sinon.stub().resolves([]), + getPythonProject: sinon.stub().returns(undefined), + } as unknown as PythonEnvironmentApi; + + const result = await createStepBasedCondaFlow( + api, + createMockLogOutputChannel(), + {} as EnvironmentManager, + Uri.file('workspace'), + ); + + assert.strictEqual(result, createdEnvironment); + assert.strictEqual((showQuickPickStub.firstCall.args[0] as QuickPickItem[])[0].label, '명명됨'); + assert.ok(showInputBoxStub.calledOnce); + assert.ok(createNamedStub.calledOnceWithExactly(api, sinon.match.any, sinon.match.any, 'localized-env', '3.12')); + assert.ok(createPrefixStub.notCalled); + }); +}); + suite('CondaEnvManager.create - orchestration', () => { let createCondaStub: sinon.SinonStub; let generateNameStub: sinon.SinonStub; diff --git a/src/test/managers/conda/condaStepBasedFlow.unit.test.ts b/src/test/managers/conda/condaStepBasedFlow.unit.test.ts deleted file mode 100644 index 0649f1605..000000000 --- a/src/test/managers/conda/condaStepBasedFlow.unit.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import assert from 'assert'; -import * as sinon from 'sinon'; -import { QuickPickItem, Uri } from 'vscode'; -import { EnvironmentManager, PythonEnvironment, PythonEnvironmentApi } from '../../../api'; -import { CondaStrings } from '../../../common/localize'; -import * as windowApis from '../../../common/window.apis'; -import { createStepBasedCondaFlow } from '../../../managers/conda/condaStepBasedFlow'; -import * as condaUtils from '../../../managers/conda/condaUtils'; -import { createMockLogOutputChannel } from '../../mocks/helper'; - -suite('Conda step-based create flow', () => { - let originalCondaNamed: string; - - setup(() => { - originalCondaNamed = CondaStrings.condaNamed; - Object.defineProperty(CondaStrings, 'condaNamed', { value: '명명됨', configurable: true }); - }); - - teardown(() => { - sinon.restore(); - Object.defineProperty(CondaStrings, 'condaNamed', { value: originalCondaNamed, configurable: true }); - }); - - test('routes a localized Named selection to named environment creation', async () => { - const createdEnvironment = {} as PythonEnvironment; - const showQuickPickStub = sinon.stub(windowApis, 'showQuickPickWithButtons'); - showQuickPickStub.onFirstCall().callsFake(async (items: readonly QuickPickItem[]) => items[0]); - showQuickPickStub.onSecondCall().resolves({ label: 'Python', description: '3.12' } as QuickPickItem); - const showInputBoxStub = sinon.stub(windowApis, 'showInputBoxWithButtons').resolves('localized-env'); - const createNamedStub = sinon.stub(condaUtils, 'createNamedCondaEnvironment').resolves(createdEnvironment); - const createPrefixStub = sinon.stub(condaUtils, 'createPrefixCondaEnvironment'); - const api = { - getEnvironments: sinon.stub().resolves([]), - getPythonProject: sinon.stub().returns(undefined), - } as unknown as PythonEnvironmentApi; - - const result = await createStepBasedCondaFlow( - api, - createMockLogOutputChannel(), - {} as EnvironmentManager, - Uri.file('workspace'), - ); - - assert.strictEqual(result, createdEnvironment); - assert.strictEqual((showQuickPickStub.firstCall.args[0] as QuickPickItem[])[0].label, '명명됨'); - assert.ok(showInputBoxStub.calledOnce); - assert.ok(createNamedStub.calledOnceWithExactly(api, sinon.match.any, sinon.match.any, 'localized-env', '3.12')); - assert.ok(createPrefixStub.notCalled); - }); -}); From 5cac492354c8fd547bb337d45030a44a4c6f60e8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 8 Sep 2026 23:01:17 +0000 Subject: [PATCH 4/4] Add conda named label fallback Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com> --- src/managers/conda/condaStepBasedFlow.ts | 13 ++++++--- .../condaEnvManager.createRemove.unit.test.ts | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/managers/conda/condaStepBasedFlow.ts b/src/managers/conda/condaStepBasedFlow.ts index b10e15a67..8b5b2ced7 100644 --- a/src/managers/conda/condaStepBasedFlow.ts +++ b/src/managers/conda/condaStepBasedFlow.ts @@ -14,6 +14,11 @@ import { // Recommended Python version for Conda environments const RECOMMENDED_CONDA_PYTHON = '3.11.11'; +const DEFAULT_CONDA_NAMED_LABEL = 'Named'; + +function getCondaNamedLabel(): string { + return CondaStrings.condaNamed || DEFAULT_CONDA_NAMED_LABEL; +} /** * State interface for the Conda environment creation flow. @@ -60,13 +65,13 @@ async function selectEnvironmentType(state: CondaCreationState): Promise 1) { - state.envType = CondaStrings.condaNamed; + state.envType = getCondaNamedLabel(); return selectPythonVersion; } const selection = (await showQuickPickWithButtons( [ - { label: CondaStrings.condaNamed, description: CondaStrings.condaNamedDescription }, + { label: getCondaNamedLabel(), description: CondaStrings.condaNamedDescription }, { label: CondaStrings.condaPrefix, description: CondaStrings.condaPrefixDescription }, ], { @@ -129,7 +134,7 @@ async function selectPythonVersion(state: CondaCreationState): Promise { assert.ok(createNamedStub.calledOnceWithExactly(api, sinon.match.any, sinon.match.any, 'localized-env', '3.12')); assert.ok(createPrefixStub.notCalled); }); + + test('falls back to English Named when the localized label is unavailable', async () => { + Object.defineProperty(CondaStrings, 'condaNamed', { value: undefined, configurable: true }); + const createdEnvironment = {} as PythonEnvironment; + const showQuickPickStub = sinon.stub(windowApis, 'showQuickPickWithButtons'); + showQuickPickStub.resolves({ label: 'Python', description: '3.12' } as QuickPickItem); + const showInputBoxStub = sinon.stub(windowApis, 'showInputBoxWithButtons').resolves('fallback-env'); + const createNamedStub = sinon.stub(condaUtils, 'createNamedCondaEnvironment').resolves(createdEnvironment); + const createPrefixStub = sinon.stub(condaUtils, 'createPrefixCondaEnvironment'); + const api = { + getEnvironments: sinon.stub().resolves([]), + getPythonProject: sinon.stub().returns(undefined), + } as unknown as PythonEnvironmentApi; + + const result = await createStepBasedCondaFlow( + api, + createMockLogOutputChannel(), + {} as EnvironmentManager, + [Uri.file(testPath('workspace', 'one')), Uri.file(testPath('workspace', 'two'))], + ); + + assert.strictEqual(result, createdEnvironment); + assert.ok(showQuickPickStub.calledOnce); + assert.ok(showInputBoxStub.calledOnce); + assert.ok(createNamedStub.calledOnceWithExactly(api, sinon.match.any, sinon.match.any, 'fallback-env', '3.12')); + assert.ok(createPrefixStub.notCalled); + }); }); suite('CondaEnvManager.create - orchestration', () => {