"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 () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const assert = __importStar(require("assert"));
const utils_1 = require("../../../src/lib/documents/utils");
const vscode_languageserver_1 = require("vscode-languageserver");
describe('document/utils', () => {
    describe('extractTag', () => {
        it('supports boolean attributes', () => {
            const extracted = (0, utils_1.extractStyleTag)('<style test></style>');
            assert.deepStrictEqual(extracted?.attributes, { test: 'test' });
        });
        it('supports unquoted attributes', () => {
            const extracted = (0, utils_1.extractStyleTag)('<style type=text/css></style>');
            assert.deepStrictEqual(extracted?.attributes, {
                type: 'text/css'
            });
        });
        it('does not extract style tag inside comment', () => {
            const text = `
                <p>bla</p>
                <!--<style>h1{ color: blue; }</style>-->
                <style>p{ color: blue; }</style>
            `;
            assert.deepStrictEqual((0, utils_1.extractStyleTag)(text), {
                content: 'p{ color: blue; }',
                attributes: {},
                start: 108,
                end: 125,
                startPos: vscode_languageserver_1.Position.create(3, 23),
                endPos: vscode_languageserver_1.Position.create(3, 40),
                container: { start: 101, end: 133 }
            });
        });
        it('does not extract tags starting with style/script', () => {
            // https://github.com/sveltejs/language-tools/issues/43
            // this would previously match <styles>....</style> due to misconfigured attribute matching regex
            const text = `
            <styles>p{ color: blue; }</styles>
            <p>bla</p>
            ></style>
            `;
            assert.deepStrictEqual((0, utils_1.extractStyleTag)(text), null);
        });
        it('is case sensitive to style/script', () => {
            const text = `
            <Style></Style>
            <Script></Script>
            `;
            assert.deepStrictEqual((0, utils_1.extractStyleTag)(text), null);
            assert.deepStrictEqual((0, utils_1.extractScriptTags)(text), null);
        });
        it('only extract attribute until tag ends', () => {
            const text = `
            <script type="typescript">
            () => abc
            </script>
            `;
            const extracted = (0, utils_1.extractScriptTags)(text);
            const attributes = extracted?.script?.attributes;
            assert.deepStrictEqual(attributes, { type: 'typescript' });
        });
        it('can extract with self-closing component before it', () => {
            const extracted = (0, utils_1.extractStyleTag)('<SelfClosing /><style></style>');
            assert.deepStrictEqual(extracted, {
                start: 22,
                end: 22,
                startPos: {
                    character: 22,
                    line: 0
                },
                endPos: {
                    character: 22,
                    line: 0
                },
                attributes: {},
                content: '',
                container: {
                    end: 30,
                    start: 15
                }
            });
        });
        it('can extract with unclosed component after it', () => {
            const extracted = (0, utils_1.extractStyleTag)('<style></style><C {#if asd}<p>asd</p>{/if}');
            assert.deepStrictEqual(extracted, {
                start: 7,
                end: 7,
                startPos: {
                    character: 7,
                    line: 0
                },
                endPos: {
                    character: 7,
                    line: 0
                },
                attributes: {},
                content: '',
                container: {
                    start: 0,
                    end: 15
                }
            });
        });
        it('extracts style tag', () => {
            const text = `
                <p>bla</p>
                <style>p{ color: blue; }</style>
            `;
            assert.deepStrictEqual((0, utils_1.extractStyleTag)(text), {
                content: 'p{ color: blue; }',
                attributes: {},
                start: 51,
                end: 68,
                startPos: vscode_languageserver_1.Position.create(2, 23),
                endPos: vscode_languageserver_1.Position.create(2, 40),
                container: { start: 44, end: 76 }
            });
        });
        it('extracts style tag with attributes', () => {
            const text = `
                <style lang="scss">p{ color: blue; }</style>
            `;
            assert.deepStrictEqual((0, utils_1.extractStyleTag)(text), {
                content: 'p{ color: blue; }',
                attributes: { lang: 'scss' },
                start: 36,
                end: 53,
                startPos: vscode_languageserver_1.Position.create(1, 35),
                endPos: vscode_languageserver_1.Position.create(1, 52),
                container: { start: 17, end: 61 }
            });
        });
        it('extracts style tag with attributes and extra whitespace', () => {
            const text = `
                <style     lang="scss"    >  p{ color: blue; }  </style>
            `;
            assert.deepStrictEqual((0, utils_1.extractStyleTag)(text), {
                content: '  p{ color: blue; }  ',
                attributes: { lang: 'scss' },
                start: 44,
                end: 65,
                startPos: vscode_languageserver_1.Position.create(1, 43),
                endPos: vscode_languageserver_1.Position.create(1, 64),
                container: { start: 17, end: 73 }
            });
        });
        it('extracts script tag with attribute with > in it', () => {
            const text = `
                <script lang="ts" generics="T extends Record<string, any>">content</script>
                <p>bla</p>
            `;
            assert.deepStrictEqual((0, utils_1.extractScriptTags)(text)?.script, {
                content: 'content',
                attributes: {
                    generics: 'T extends Record<string, any>',
                    lang: 'ts'
                },
                start: 76,
                end: 83,
                startPos: vscode_languageserver_1.Position.create(1, 75),
                endPos: vscode_languageserver_1.Position.create(1, 82),
                container: { start: 17, end: 92 }
            });
        });
        it('extracts top level script tag only', () => {
            const text = `
                {#if name}
                    <script>
                        console.log('if not top level')
                    </script>
                {/if}
                <ul>
                    {#each cats as cat}
                        <script>
                            console.log('each not top level')
                        </script>
                    {/each}
                </ul>
                {#await promise}
                    <script>
                        console.log('await not top level')
                    </script>
                {:then number}
                    <script>
                        console.log('then not top level')
                    </script>
                {:catch error}
                    <script>
                        console.log('catch not top level')
                    </script>
                {/await}
                <p>{@html <script> console.log('html not top level')</script>}</p>
                {@html mycontent}
                {@debug myvar}
                <!-- p{ color: blue; }</script> -->
                <!--<script lang="scss">
                p{ color: blue; }
                </script> -->
                <scrit>blah</scrit>
                <script>top level script</script>
            `;
            assert.deepStrictEqual((0, utils_1.extractScriptTags)(text)?.script, {
                content: 'top level script',
                attributes: {},
                start: 1243,
                end: 1259,
                startPos: vscode_languageserver_1.Position.create(34, 24),
                endPos: vscode_languageserver_1.Position.create(34, 40),
                container: { start: 1235, end: 1268 }
            });
        });
        it("extracts top level script when there're whitespace before block name", () => {
            const text = `
                <script>top level script</script>
                {  #if myvar } {/if}
            `;
            assert.deepStrictEqual((0, utils_1.extractScriptTags)(text)?.script, {
                content: 'top level script',
                attributes: {},
                start: 25,
                end: 41,
                startPos: vscode_languageserver_1.Position.create(1, 24),
                endPos: vscode_languageserver_1.Position.create(1, 40),
                container: { start: 17, end: 50 }
            });
        });
        it('ignores script tag in svelte:head', () => {
            // https://github.com/sveltejs/language-tools/issues/143#issuecomment-636422045
            const text = `
            <svelte:head>
                <link rel="stylesheet" href="/lib/jodit.es2018.min.css" />
                <script src="/lib/jodit.es2018.min.js"> 
                </script>
            </svelte:head>
            <p>jo</p>
            <script>top level script</script>
            <h1>Hello, world!</h1>
            <style>.bla {}</style>
            `;
            assert.deepStrictEqual((0, utils_1.extractScriptTags)(text)?.script, {
                content: 'top level script',
                attributes: {},
                start: 254,
                end: 270,
                startPos: vscode_languageserver_1.Position.create(7, 20),
                endPos: vscode_languageserver_1.Position.create(7, 36),
                container: { start: 246, end: 279 }
            });
        });
        it('extracts script and module script', () => {
            const text = `
            <script context="module">a</script>
            <script>b</script>
            `;
            assert.deepStrictEqual((0, utils_1.extractScriptTags)(text), {
                moduleScript: {
                    attributes: {
                        context: 'module'
                    },
                    container: {
                        end: 48,
                        start: 13
                    },
                    content: 'a',
                    start: 38,
                    end: 39,
                    startPos: {
                        character: 37,
                        line: 1
                    },
                    endPos: {
                        character: 38,
                        line: 1
                    }
                },
                script: {
                    attributes: {},
                    container: {
                        end: 79,
                        start: 61
                    },
                    content: 'b',
                    start: 69,
                    end: 70,
                    startPos: {
                        character: 20,
                        line: 2
                    },
                    endPos: {
                        character: 21,
                        line: 2
                    }
                }
            });
        });
        it('extract tag correctly with #if and < operator', () => {
            const text = `
            {#if value < 3}
              <div>
                bla
              </div>
            {:else if value < 4}
            {/if}
          <script>let value = 2</script>

          <div>
            {#if value < 3}
              <div>
                bla
              </div>
            {:else if value < 4}
            {/if}
          </div>`;
            assert.deepStrictEqual((0, utils_1.extractScriptTags)(text)?.script, {
                content: 'let value = 2',
                attributes: {},
                start: 159,
                end: 172,
                startPos: vscode_languageserver_1.Position.create(7, 18),
                endPos: vscode_languageserver_1.Position.create(7, 31),
                container: { start: 151, end: 181 }
            });
        });
        it('extract tag correctly if nothing is before the tag', () => {
            const text = `<script>let value = 2</script>
                {/if}`;
            assert.deepStrictEqual((0, utils_1.extractScriptTags)(text)?.script, {
                content: 'let value = 2',
                attributes: {},
                start: 8,
                end: 21,
                startPos: vscode_languageserver_1.Position.create(0, 8),
                endPos: vscode_languageserver_1.Position.create(0, 21),
                container: { start: 0, end: 30 }
            });
        });
    });
    describe('#getLineAtPosition', () => {
        it('should return line at position (only one line)', () => {
            assert.deepStrictEqual((0, utils_1.getLineAtPosition)(vscode_languageserver_1.Position.create(0, 1), 'ABC'), 'ABC');
        });
        it('should return line at position (multiple lines)', () => {
            assert.deepStrictEqual((0, utils_1.getLineAtPosition)(vscode_languageserver_1.Position.create(1, 1), 'ABC\nDEF\nGHI'), 'DEF\n');
        });
    });
    describe('#updateRelativeImport', () => {
        it('should update path of component with ending', () => {
            const newPath = (0, utils_1.updateRelativeImport)('C:/absolute/path/oldPath', 'C:/absolute/newPath', './Component.svelte');
            assert.deepStrictEqual(newPath, '../path/oldPath/Component.svelte');
        });
        it('should update path of file without ending', () => {
            const newPath = (0, utils_1.updateRelativeImport)('C:/absolute/path/oldPath', 'C:/absolute/newPath', './someTsFile');
            assert.deepStrictEqual(newPath, '../path/oldPath/someTsFile');
        });
        it('should update path of file going one up', () => {
            const newPath = (0, utils_1.updateRelativeImport)('C:/absolute/path/oldPath', 'C:/absolute/path', './someTsFile');
            assert.deepStrictEqual(newPath, './oldPath/someTsFile');
        });
    });
    describe('#getWordAt', () => {
        it('returns word between whitespaces', () => {
            assert.equal((0, utils_1.getWordAt)('qwd asd qwd', 5), 'asd');
        });
        it('returns word between whitespace and end of string', () => {
            assert.equal((0, utils_1.getWordAt)('qwd asd', 5), 'asd');
        });
        it('returns word between start of string and whitespace', () => {
            assert.equal((0, utils_1.getWordAt)('asd qwd', 2), 'asd');
        });
        it('returns word between start of string and end of string', () => {
            assert.equal((0, utils_1.getWordAt)('asd', 2), 'asd');
        });
        it('returns word with custom delimiters', () => {
            assert.equal((0, utils_1.getWordAt)('asd on:asd-qwd="asd" ', 10, { left: /\S+$/, right: /[\s=]/ }), 'on:asd-qwd');
        });
        function testEvent(str, pos, expected) {
            assert.equal((0, utils_1.getWordAt)(str, pos, { left: /\S+$/, right: /[^\w$:]/ }), expected);
        }
        it('returns event #1', () => {
            testEvent('<div on:>', 8, 'on:');
        });
        it('returns event #2', () => {
            testEvent('<div on: >', 8, 'on:');
        });
        it('returns empty string when only whitespace', () => {
            assert.equal((0, utils_1.getWordAt)('a  a', 2), '');
        });
    });
    describe('#isInsideMoustacheTag', () => {
        it('detects position inside moustache tag', () => {
            const result = (0, utils_1.isInsideMoustacheTag)('<div on:click={() => console.log("hello")}></div>', 0, 20);
            assert.strictEqual(result, true);
        });
        it('detects position after template literal', () => {
            const result = (0, utils_1.isInsideMoustacheTag)('<Foo a={`a}`}></div>', 0, 11);
            assert.strictEqual(result, true);
        });
        it('detects position after nested template literals', () => {
            const result = (0, utils_1.isInsideMoustacheTag)('<Foo a={`${`}`}`}></div>', 0, 15);
            assert.strictEqual(result, true);
        });
        it('detects position after nested template literals with interpolation', () => {
            const result = (0, utils_1.isInsideMoustacheTag)('<Foo a={`${hi(`${a}}`)}`)></div>', 0, 22);
            assert.strictEqual(result, true);
        });
    });
});
//# sourceMappingURL=utils.test.js.map