"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const path_1 = require("path");
const typescript_1 = __importDefault(require("typescript"));
const vscode_languageserver_1 = require("vscode-languageserver");
const documents_1 = require("../../../../src/lib/documents");
const ls_config_1 = require("../../../../src/ls-config");
const CodeActionsProvider_1 = require("../../../../src/plugins/typescript/features/CodeActionsProvider");
const CompletionProvider_1 = require("../../../../src/plugins/typescript/features/CompletionProvider");
const LSAndTSDocResolver_1 = require("../../../../src/plugins/typescript/LSAndTSDocResolver");
const utils_1 = require("../../../../src/utils");
const test_utils_1 = require("../test-utils");
const testFilesDir = (0, path_1.join)(__dirname, '..', 'testfiles', 'preferences');
describe('ts user preferences', function () {
    (0, test_utils_1.serviceWarmup)(this, testFilesDir);
    function setup(filename) {
        const docManager = new documents_1.DocumentManager((textDocument) => documents_1.Document.createForTest(textDocument.uri, textDocument.text));
        const filePath = (0, path_1.join)(testFilesDir, filename);
        const document = docManager.openClientDocument({
            uri: (0, utils_1.pathToUrl)(filePath),
            text: typescript_1.default.sys.readFile(filePath) || ''
        });
        return { document, docManager };
    }
    const expectedImportEdit = "import { definition } from '~/definition/index';";
    function getPreferences() {
        return {
            preferences: {
                ...getDefaultPreferences(),
                importModuleSpecifier: 'non-relative',
                importModuleSpecifierEnding: 'index'
            },
            suggest: {
                autoImports: true,
                includeAutomaticOptionalChainCompletions: undefined,
                includeCompletionsForImportStatements: undefined,
                classMemberSnippets: undefined,
                objectLiteralMethodSnippets: undefined,
                includeCompletionsWithSnippetText: undefined
            }
        };
    }
    function createLSAndTSDocResolver(docManager, preferences) {
        const configManager = new ls_config_1.LSConfigManager();
        configManager.updateTsJsUserPreferences({
            typescript: { ...getPreferences(), ...preferences },
            javascript: { ...getPreferences(), ...preferences }
        });
        return {
            lsAndTsDocResolver: new LSAndTSDocResolver_1.LSAndTSDocResolver(docManager, [(0, utils_1.pathToUrl)(testFilesDir)], configManager),
            configManager
        };
    }
    function getDefaultPreferences() {
        return {
            autoImportFileExcludePatterns: undefined,
            importModuleSpecifier: 'non-relative',
            importModuleSpecifierEnding: undefined,
            quoteStyle: 'single',
            includePackageJsonAutoImports: undefined,
            organizeImports: undefined
        };
    }
    it('provides auto import completion according to preferences', async () => {
        const { docManager, document } = setup('code-action.svelte');
        const { lsAndTsDocResolver, configManager } = createLSAndTSDocResolver(docManager);
        const completionProvider = new CompletionProvider_1.CompletionsProviderImpl(lsAndTsDocResolver, configManager);
        const completions = await completionProvider.getCompletions(document, vscode_languageserver_1.Position.create(1, 14));
        const item = completions?.items.find((item) => item.label === 'definition');
        const { additionalTextEdits } = await completionProvider.resolveCompletion(document, item);
        assert_1.default.strictEqual(additionalTextEdits[0].newText.trim(), expectedImportEdit);
    });
    async function importCodeActionTest(filename, range, context) {
        const { docManager, document } = setup(filename);
        const { lsAndTsDocResolver, configManager } = createLSAndTSDocResolver(docManager);
        const completionProvider = new CompletionProvider_1.CompletionsProviderImpl(lsAndTsDocResolver, configManager);
        const codeActionProvider = new CodeActionsProvider_1.CodeActionsProviderImpl(lsAndTsDocResolver, completionProvider, configManager);
        const codeAction = await codeActionProvider.getCodeActions(document, range, context);
        const documentChange = codeAction[0].edit?.documentChanges?.[0];
        assert_1.default.strictEqual(documentChange?.edits[0].newText.trim(), expectedImportEdit);
    }
    it('provides auto import code action according to preferences', async () => {
        const range = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(1, 4), vscode_languageserver_1.Position.create(1, 14));
        await importCodeActionTest('code-action.svelte', range, {
            diagnostics: [
                vscode_languageserver_1.Diagnostic.create(range, "Cannot find name 'definition'", vscode_languageserver_1.DiagnosticSeverity.Error, 2304, 'ts')
            ]
        });
    });
    it('provides auto import suggestions according to preferences', async () => {
        const { docManager, document } = setup('code-action.svelte');
        const { lsAndTsDocResolver, configManager } = createLSAndTSDocResolver(docManager, {
            suggest: {
                autoImports: false,
                includeAutomaticOptionalChainCompletions: undefined,
                includeCompletionsForImportStatements: undefined,
                classMemberSnippets: undefined,
                objectLiteralMethodSnippets: undefined,
                includeCompletionsWithSnippetText: undefined
            }
        });
        const completionProvider = new CompletionProvider_1.CompletionsProviderImpl(lsAndTsDocResolver, configManager);
        const completions = await completionProvider.getCompletions(document, vscode_languageserver_1.Position.create(1, 14));
        const item = completions?.items.find((item) => item.label === 'definition');
        assert_1.default.strictEqual(item, undefined, 'Expected no auto import suggestions');
    });
    const expectedComponentImportEdit = "import Imports from '~/imports.svelte';";
    function setupImportModuleSpecifierEndingJs() {
        const { docManager, document } = setup('module-specifier-js.svelte');
        const { lsAndTsDocResolver, configManager } = createLSAndTSDocResolver(docManager, {
            preferences: {
                ...getDefaultPreferences(),
                importModuleSpecifierEnding: 'js'
            }
        });
        return { document, lsAndTsDocResolver, configManager };
    }
    it('provides auto import for svelte component when importModuleSpecifierEnding is js', async () => {
        const { document, lsAndTsDocResolver } = setupImportModuleSpecifierEndingJs();
        const completionProvider = new CompletionProvider_1.CompletionsProviderImpl(lsAndTsDocResolver, new ls_config_1.LSConfigManager());
        const completions = await completionProvider.getCompletions(document, vscode_languageserver_1.Position.create(4, 8));
        const item = completions?.items.find((item) => item.label === 'Imports');
        const { additionalTextEdits } = await completionProvider.resolveCompletion(document, item);
        assert_1.default.strictEqual(additionalTextEdits[0].newText.trim(), expectedComponentImportEdit);
    });
    it('provides auto import for context="module" export when importModuleSpecifierEnding is js', async () => {
        const { document, lsAndTsDocResolver } = setupImportModuleSpecifierEndingJs();
        const completionProvider = new CompletionProvider_1.CompletionsProviderImpl(lsAndTsDocResolver, new ls_config_1.LSConfigManager());
        const completions = await completionProvider.getCompletions(document, vscode_languageserver_1.Position.create(1, 6));
        const item = completions?.items.find((item) => item.label === 'hi');
        const { additionalTextEdits } = await completionProvider.resolveCompletion(document, item);
        assert_1.default.strictEqual(additionalTextEdits[0].newText.trim(), "import { hi } from '~/with-context-module.svelte';");
    });
    it('provides import code action for svelte component when importModuleSpecifierEnding is js', async () => {
        const range = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(4, 1), vscode_languageserver_1.Position.create(4, 8));
        const { document, lsAndTsDocResolver } = setupImportModuleSpecifierEndingJs();
        const completionProvider = new CompletionProvider_1.CompletionsProviderImpl(lsAndTsDocResolver, new ls_config_1.LSConfigManager());
        const codeActionProvider = new CodeActionsProvider_1.CodeActionsProviderImpl(lsAndTsDocResolver, completionProvider, new ls_config_1.LSConfigManager());
        const codeAction = await codeActionProvider.getCodeActions(document, range, {
            diagnostics: [
                vscode_languageserver_1.Diagnostic.create(range, "Cannot find name 'Imports'", vscode_languageserver_1.DiagnosticSeverity.Error, 2304, 'ts')
            ]
        });
        const documentChange = codeAction[0].edit?.documentChanges?.[0];
        assert_1.default.strictEqual(documentChange?.edits[0].newText.trim(), expectedComponentImportEdit);
    });
    async function testExcludeDefinitionDir(pattern) {
        const { docManager, document } = setup('code-action.svelte');
        const { lsAndTsDocResolver, configManager } = createLSAndTSDocResolver(docManager, {
            preferences: {
                ...getDefaultPreferences(),
                autoImportFileExcludePatterns: [pattern]
            }
        });
        const completionProvider = new CompletionProvider_1.CompletionsProviderImpl(lsAndTsDocResolver, configManager);
        const completions = await completionProvider.getCompletions(document, vscode_languageserver_1.Position.create(1, 14));
        const item = completions?.items.find((item) => item.label === 'definition');
        assert_1.default.equal(item, undefined);
    }
    it('exclude auto import', async () => {
        await testExcludeDefinitionDir('definition');
    });
    it('exclude auto import (relative pattern)', async () => {
        await testExcludeDefinitionDir('./definition');
    });
    it('exclude auto import (**/ pattern)', async () => {
        await testExcludeDefinitionDir('**/definition');
    });
    it('exclude auto import outside of the root', async () => {
        const { docManager, document } = setup('code-action-outside-root.svelte');
        const { lsAndTsDocResolver, configManager } = createLSAndTSDocResolver(docManager, {
            preferences: {
                ...getDefaultPreferences(),
                autoImportFileExcludePatterns: ['definitions.ts']
            }
        });
        const completionProvider = new CompletionProvider_1.CompletionsProviderImpl(lsAndTsDocResolver, configManager);
        const completions = await completionProvider.getCompletions(document, vscode_languageserver_1.Position.create(4, 7));
        const item = completions?.items.find((item) => item.label === 'blubb');
        assert_1.default.equal(item, undefined);
    });
});
//# sourceMappingURL=preferences.test.js.map