<commit_before>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

'use strict';

import { expect, use } from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import { execFile } from 'child_process';
import * as fs from 'fs-extra';
import { EOL } from 'os';
import * as path from 'path';
import { ConfigurationTarget, Uri } from 'vscode';
import { IPythonExecutionFactory, StdErrError } from '../../../client/common/process/types';
import { IConfigurationService } from '../../../client/common/types';
import { clearCache } from '../../../client/common/utils/cacheUtils';
import { IServiceContainer } from '../../../client/ioc/types';
import { initializeExternalDependencies } from '../../../client/pythonEnvironments/common/externalDependencies';
import { clearPythonPathInWorkspaceFolder } from '../../common';
import { getExtensionSettings } from '../../extensionSettings';
import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST, TEST_TIMEOUT } from '../../initialize';

use(chaiAsPromised);

const multirootPath = path.join(__dirname, '..', '..', '..', '..', 'src', 'testMultiRootWkspc');
const workspace4Path = Uri.file(path.join(multirootPath, 'workspace4'));
const workspace4PyFile = Uri.file(path.join(workspace4Path.fsPath, 'one.py'));

suite('PythonExecutableService', () => {
    let serviceContainer: IServiceContainer;
    let configService: IConfigurationService;
    let pythonExecFactory: IPythonExecutionFactory;

    suiteSetup(async function () {
        if (!IS_MULTI_ROOT_TEST) {
            this.skip();
        }
        await clearPythonPathInWorkspaceFolder(workspace4Path);
        serviceContainer = (await initialize()).serviceContainer;
    });
    setup(async () => {
        initializeExternalDependencies(serviceContainer);
        configService = serviceContainer.get<IConfigurationService>(IConfigurationService);
        pythonExecFactory = serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory);

        await configService.updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder);
        clearCache();
        return initializeTest();
    });
    suiteTeardown(closeActiveWindows);
    teardown(async () => {
        await closeActiveWindows();
        await clearPythonPathInWorkspaceFolder(workspace4Path);
        await configService.updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder);
        await initializeTest();
        clearCache();
    });

    test('Importing without a valid PYTHONPATH should fail', async () => {
        await configService.updateSetting(
            'envFile',
            'someInvalidFile.env',
            workspace4PyFile,
            ConfigurationTarget.WorkspaceFolder,
        );
        pythonExecFactory = serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory);
        const pythonExecService = await pythonExecFactory.create({ resource: workspace4PyFile });
        const promise = pythonExecService.exec([workspace4PyFile.fsPath], {
            cwd: path.dirname(workspace4PyFile.fsPath),
            throwOnStdErr: true,
        });

        await expect(promise).to.eventually.be.rejectedWith(StdErrError);
    }).timeout(TEST_TIMEOUT * 3);

    test('Importing with a valid PYTHONPATH from .env file should succeed', async () => {
        await configService.updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder);
        const pythonExecService = await pythonExecFactory.create({ resource: workspace4PyFile });
        const promise = pythonExecService.exec([workspace4PyFile.fsPath], {
            cwd: path.dirname(workspace4PyFile.fsPath),
            throwOnStdErr: true,
        });

        await expect(promise).to.eventually.have.property('stdout', `Hello${EOL}`);
    }).timeout(TEST_TIMEOUT * 3);

    test("Known modules such as 'os' and 'sys' should be deemed 'installed'", async () => {
        const pythonExecService = await pythonExecFactory.create({ resource: workspace4PyFile });
        const osModuleIsInstalled = pythonExecService.isModuleInstalled('os');
        const sysModuleIsInstalled = pythonExecService.isModuleInstalled('sys');
        await expect(osModuleIsInstalled).to.eventually.equal(true, 'os module is not installed');
        await expect(sysModuleIsInstalled).to.eventually.equal(true, 'sys module is not installed');
    }).timeout(TEST_TIMEOUT * 3);

    test("Unknown modules such as 'xyzabc123' be deemed 'not installed'", async () => {
        const pythonExecService = await pythonExecFactory.create({ resource: workspace4PyFile });
        const randomModuleName = `xyz123${new Date().getSeconds()}`;
        const randomModuleIsInstalled = pythonExecService.isModuleInstalled(randomModuleName);
        await expect(randomModuleIsInstalled).to.eventually.equal(
            false,
            `Random module '${randomModuleName}' is installed`,
        );
    }).timeout(TEST_TIMEOUT * 3);

    test('Ensure correct path to executable is returned', async () => {
        const { pythonPath } = getExtensionSettings(workspace4Path);
        let expectedExecutablePath: string;
        if (await fs.pathExists(pythonPath)) {
            expectedExecutablePath = pythonPath;<commit_msg>Fix test line endings (#18400)<commit_after>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

'use strict';

import { expect, use } from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import { execFile } from 'child_process';
import * as fs from 'fs-extra';
import * as path from 'path';
import { ConfigurationTarget, Uri } from 'vscode';
import { IPythonExecutionFactory, StdErrError } from '../../../client/common/process/types';
import { IConfigurationService } from '../../../client/common/types';
import { clearCache } from '../../../client/common/utils/cacheUtils';
import { IServiceContainer } from '../../../client/ioc/types';
import { initializeExternalDependencies } from '../../../client/pythonEnvironments/common/externalDependencies';
import { clearPythonPathInWorkspaceFolder } from '../../common';
import { getExtensionSettings } from '../../extensionSettings';
import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST, TEST_TIMEOUT } from '../../initialize';

use(chaiAsPromised);

const multirootPath = path.join(__dirname, '..', '..', '..', '..', 'src', 'testMultiRootWkspc');
const workspace4Path = Uri.file(path.join(multirootPath, 'workspace4'));
const workspace4PyFile = Uri.file(path.join(workspace4Path.fsPath, 'one.py'));

suite('PythonExecutableService', () => {
    let serviceContainer: IServiceContainer;
    let configService: IConfigurationService;
    let pythonExecFactory: IPythonExecutionFactory;

    suiteSetup(async function () {
        if (!IS_MULTI_ROOT_TEST) {
            this.skip();
        }
        await clearPythonPathInWorkspaceFolder(workspace4Path);
        serviceContainer = (await initialize()).serviceContainer;
    });
    setup(async () => {
        initializeExternalDependencies(serviceContainer);
        configService = serviceContainer.get<IConfigurationService>(IConfigurationService);
        pythonExecFactory = serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory);

        await configService.updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder);
        clearCache();
        return initializeTest();
    });
    suiteTeardown(closeActiveWindows);
    teardown(async () => {
        await closeActiveWindows();
        await clearPythonPathInWorkspaceFolder(workspace4Path);
        await configService.updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder);
        await initializeTest();
        clearCache();
    });

    test('Importing without a valid PYTHONPATH should fail', async () => {
        await configService.updateSetting(
            'envFile',
            'someInvalidFile.env',
            workspace4PyFile,
            ConfigurationTarget.WorkspaceFolder,
        );
        pythonExecFactory = serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory);
        const pythonExecService = await pythonExecFactory.create({ resource: workspace4PyFile });
        const promise = pythonExecService.exec([workspace4PyFile.fsPath], {
            cwd: path.dirname(workspace4PyFile.fsPath),
            throwOnStdErr: true,
        });

        await expect(promise).to.eventually.be.rejectedWith(StdErrError);
    }).timeout(TEST_TIMEOUT * 3);

    test('Importing with a valid PYTHONPATH from .env file should succeed', async () => {
        await configService.updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder);
        const pythonExecService = await pythonExecFactory.create({ resource: workspace4PyFile });
        const result = await pythonExecService.exec([workspace4PyFile.fsPath], {
            cwd: path.dirname(workspace4PyFile.fsPath),
            throwOnStdErr: true,
        });

        expect(result.stdout.startsWith('Hello')).to.be.equals(true);
    }).timeout(TEST_TIMEOUT * 3);

    test("Known modules such as 'os' and 'sys' should be deemed 'installed'", async () => {
        const pythonExecService = await pythonExecFactory.create({ resource: workspace4PyFile });
        const osModuleIsInstalled = pythonExecService.isModuleInstalled('os');
        const sysModuleIsInstalled = pythonExecService.isModuleInstalled('sys');
        await expect(osModuleIsInstalled).to.eventually.equal(true, 'os module is not installed');
        await expect(sysModuleIsInstalled).to.eventually.equal(true, 'sys module is not installed');
    }).timeout(TEST_TIMEOUT * 3);

    test("Unknown modules such as 'xyzabc123' be deemed 'not installed'", async () => {
        const pythonExecService = await pythonExecFactory.create({ resource: workspace4PyFile });
        const randomModuleName = `xyz123${new Date().getSeconds()}`;
        const randomModuleIsInstalled = pythonExecService.isModuleInstalled(randomModuleName);
        await expect(randomModuleIsInstalled).to.eventually.equal(
            false,
            `Random module '${randomModuleName}' is installed`,
        );
    }).timeout(TEST_TIMEOUT * 3);

    test('Ensure correct path to executable is returned', async () => {
        const { pythonPath } = getExtensionSettings(workspace4Path);
        let expectedExecutablePath: string;
        if (await fs.pathExists(pythonPath)) {
            expectedExecutablePath = pythonPath;
{'fraction_non_alphanumeric': 0.12056671045224245, 'fraction_numerical': 0.005911052730343404, 'mean_word_length': 3.7948717948717947, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '255113', 'n_tokens_mistral': 2789, 'n_tokens_neox': 2799, 'n_words': 610}