Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/managers/conda/condaStepBasedFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -60,13 +65,13 @@ async function selectEnvironmentType(state: CondaCreationState): Promise<StepFun
try {
// Skip this step if we have multiple URIs (force named environment)
if (state.uris && state.uris.length > 1) {
state.envType = 'Named';
state.envType = getCondaNamedLabel();
return selectPythonVersion;
Comment thread
edvilme marked this conversation as resolved.
}

const selection = (await showQuickPickWithButtons(
[
{ label: CondaStrings.condaNamed, description: CondaStrings.condaNamedDescription },
{ label: getCondaNamedLabel(), description: CondaStrings.condaNamedDescription },
{ label: CondaStrings.condaPrefix, description: CondaStrings.condaPrefixDescription },
],
{
Expand Down Expand Up @@ -129,7 +134,7 @@ async function selectPythonVersion(state: CondaCreationState): Promise<StepFunct
state.pythonVersion = (selection as QuickPickItem).description;

// Next step depends on environment type
return state.envType === 'Named' ? enterEnvironmentName : selectLocation;
return state.envType === getCondaNamedLabel() ? enterEnvironmentName : selectLocation;
} catch (ex) {
if (ex === QuickInputButtons.Back) {
// Go back to environment type selection
Expand Down Expand Up @@ -292,7 +297,7 @@ export async function createStepBasedCondaFlow(
}

// If we have all required data, create the environment
if (state.envType === CondaStrings.condaNamed && state.envName) {
if (state.envType === getCondaNamedLabel() && state.envName) {
return await createNamedCondaEnvironment(api, log, manager, state.envName, state.pythonVersion);
} else if (state.envType === CondaStrings.condaPrefix && state.prefix) {
// For prefix environments, we need to pass the fsPath where the environment will be created
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -46,6 +50,74 @@ function createManager(apiOverrides?: Partial<PythonEnvironmentApi>): 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);
});

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', () => {
let createCondaStub: sinon.SinonStub;
let generateNameStub: sinon.SinonStub;
Expand Down
Loading