"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert = __importStar(require("assert"));
const plugins_1 = require("../../../src/plugins");
const documents_1 = require("../../../src/lib/documents");
const vscode_languageserver_1 = require("vscode-languageserver");
const ls_config_1 = require("../../../src/ls-config");
const importPackage = __importStar(require("../../../src/importPackage"));
const sinon_1 = __importDefault(require("sinon"));
const path_1 = require("path");
const utils_1 = require("../../../src/utils");
describe('Svelte Plugin', () => {
    function setup(content, prettierConfig, { trusted = true, documentUri = 'file:///hello.svelte' } = {}) {
        const document = new documents_1.Document(documentUri, content);
        const docManager = new documents_1.DocumentManager(() => document);
        const pluginManager = new ls_config_1.LSConfigManager();
        pluginManager.updateIsTrusted(trusted);
        pluginManager.updatePrettierConfig(prettierConfig);
        const plugin = new plugins_1.SveltePlugin(pluginManager);
        docManager.openDocument('some doc');
        return { plugin, document };
    }
    it('provides diagnostic warnings', async () => {
        const { plugin, document } = setup('<h1>Hello, world!</h1>\n<img src="hello.png">');
        const diagnostics = await plugin.getDiagnostics(document);
        const diagnostic = vscode_languageserver_1.Diagnostic.create(vscode_languageserver_1.Range.create(1, 0, 1, 21), 'A11y: <img> element should have an alt attribute', vscode_languageserver_1.DiagnosticSeverity.Warning, 'a11y-missing-attribute', 'svelte');
        assert.deepStrictEqual(diagnostics, [diagnostic]);
    });
    it('provides diagnostic errors', async () => {
        const { plugin, document } = setup('<div bind:whatever></div>');
        const diagnostics = await plugin.getDiagnostics(document);
        const diagnostic = vscode_languageserver_1.Diagnostic.create(vscode_languageserver_1.Range.create(0, 10, 0, 18), 'whatever is not declared', vscode_languageserver_1.DiagnosticSeverity.Error, 'binding-undeclared', 'svelte');
        assert.deepStrictEqual(diagnostics, [diagnostic]);
    });
    it('provides no diagnostic errors when untrusted', async () => {
        const { plugin, document } = setup('<div bind:whatever></div>', {}, { trusted: false });
        const diagnostics = await plugin.getDiagnostics(document);
        assert.deepStrictEqual(diagnostics, []);
    });
    describe('#formatDocument', () => {
        function stubPrettier(config) {
            const formatStub = sinon_1.default.stub().returns('formatted');
            sinon_1.default.stub(importPackage, 'importPrettier').returns({
                resolveConfig: () => Promise.resolve(config),
                getFileInfo: () => ({ ignored: false }),
                format: formatStub,
                getSupportInfo: () => ({ languages: [{ name: 'svelte' }] })
            });
            return formatStub;
        }
        async function testFormat(config, fallbackPrettierConfig, options) {
            const { plugin, document } = setup('unformatted', fallbackPrettierConfig, options);
            const formatStub = stubPrettier(config);
            const formatted = await plugin.formatDocument(document, {
                insertSpaces: true,
                tabSize: 4
            });
            assert.deepStrictEqual(formatted, [
                {
                    newText: 'formatted',
                    range: {
                        end: {
                            character: 11,
                            line: 0
                        },
                        start: {
                            character: 0,
                            line: 0
                        }
                    }
                }
            ]);
            return formatStub;
        }
        afterEach(() => {
            sinon_1.default.restore();
        });
        it('should use config for formatting', async () => {
            const formatStub = await testFormat({ fromConfig: true }, { fallbackConfig: true });
            sinon_1.default.assert.calledOnceWithExactly(formatStub, 'unformatted', {
                fromConfig: true,
                plugins: [],
                parser: 'svelte'
            });
        });
        it('can resolve plugin for formatting', async () => {
            const documentUri = (0, utils_1.pathToUrl)((0, path_1.join)(__dirname, 'testFiles', 'do-not-exist.svelte'));
            const formatStub = await testFormat({ fromConfig: true, plugins: ['prettier-plugin-svelte'] }, { fallbackConfig: true }, { documentUri });
            sinon_1.default.assert.calledOnceWithExactly(formatStub, 'unformatted', {
                fromConfig: true,
                plugins: [
                    require.resolve('prettier-plugin-svelte', { paths: [(0, utils_1.urlToPath)(documentUri)] })
                ],
                parser: 'svelte'
            });
        });
        const defaultSettings = {
            svelteSortOrder: 'options-scripts-markup-styles',
            svelteStrictMode: false,
            svelteAllowShorthand: true,
            svelteBracketNewLine: true,
            svelteIndentScriptAndStyle: true,
            printWidth: 80,
            singleQuote: false
        };
        it('should use prettier fallback config for formatting', async () => {
            const formatStub = await testFormat(undefined, { fallbackConfig: true });
            sinon_1.default.assert.calledOnceWithExactly(formatStub, 'unformatted', {
                fallbackConfig: true,
                plugins: [],
                parser: 'svelte',
                ...defaultSettings
            });
        });
        it('should use FormattingOptions for formatting', async () => {
            const formatStub = await testFormat(undefined, undefined);
            sinon_1.default.assert.calledOnceWithExactly(formatStub, 'unformatted', {
                tabWidth: 4,
                useTabs: false,
                plugins: [],
                parser: 'svelte',
                ...defaultSettings
            });
        });
        it('should use FormattingOptions for formatting when configs are empty objects', async () => {
            const formatStub = await testFormat({}, {});
            sinon_1.default.assert.calledOnceWithExactly(formatStub, 'unformatted', {
                tabWidth: 4,
                useTabs: false,
                plugins: [],
                parser: 'svelte',
                ...defaultSettings
            });
        });
    });
    it('can cancel completion before promise resolved', async () => {
        const { plugin, document } = setup('{#');
        const cancellationTokenSource = new vscode_languageserver_1.CancellationTokenSource();
        const completionsPromise = plugin.getCompletions(document, { line: 0, character: 2 }, undefined, cancellationTokenSource.token);
        cancellationTokenSource.cancel();
        assert.deepStrictEqual(await completionsPromise, null);
    });
    it('can cancel code action before promise resolved', async () => {
        const { plugin, document } = setup('<a></a>');
        const cancellationTokenSource = new vscode_languageserver_1.CancellationTokenSource();
        const range = {
            start: { line: 0, character: 0 },
            end: { line: 0, character: 7 }
        };
        const codeActionPromise = plugin.getCodeActions(document, range, {
            diagnostics: [
                {
                    message: 'A11y: <a> element should have child content',
                    code: 'a11y-missing-content',
                    range,
                    severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                    source: 'svelte'
                }
            ]
        }, cancellationTokenSource.token);
        cancellationTokenSource.cancel();
        assert.deepStrictEqual(await codeActionPromise, []);
    });
});
//# sourceMappingURL=SveltePlugin.test.js.map