"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 fs = __importStar(require("fs"));
const os_1 = require("os");
const path = __importStar(require("path"));
const vscode_languageserver_1 = require("vscode-languageserver");
const documents_1 = require("../../../../src/lib/documents");
const getCodeActions_1 = require("../../../../src/plugins/svelte/features/getCodeActions");
const getRefactorings_1 = require("../../../../src/plugins/svelte/features/getCodeActions/getRefactorings");
const SvelteDocument_1 = require("../../../../src/plugins/svelte/SvelteDocument");
const utils_1 = require("../../../../src/utils");
describe('SveltePlugin#getCodeAction', () => {
    const testDir = path.join(__dirname, '..', 'testfiles');
    function getFullPath(filename) {
        return path.join(testDir, filename);
    }
    function getUri(filename) {
        return (0, utils_1.pathToUrl)(getFullPath(filename));
    }
    async function expectCodeActionFor(filename, context) {
        const filePath = path.join(testDir, filename);
        const document = new documents_1.Document((0, utils_1.pathToUrl)(filePath), filename ? fs.readFileSync(filePath)?.toString() : '');
        const svelteDoc = new SvelteDocument_1.SvelteDocument(document);
        const codeAction = await (0, getCodeActions_1.getCodeActions)(svelteDoc, vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(0, 0), vscode_languageserver_1.Position.create(0, 0)), context);
        return {
            toEqual: (expected) => assert.deepStrictEqual(codeAction, expected)
        };
    }
    describe('It should not provide svelte ignore code actions', () => {
        const startRange = vscode_languageserver_1.Range.create({ line: 0, character: 0 }, { line: 0, character: 1 });
        it('if no svelte diagnostic', async () => {
            (await expectCodeActionFor('', {
                diagnostics: [
                    {
                        code: 'whatever',
                        source: 'eslint',
                        range: startRange,
                        message: ''
                    }
                ]
            })).toEqual([]);
        });
        it('if no diagnostic code', async () => {
            (await expectCodeActionFor('', {
                diagnostics: [
                    {
                        source: 'svelte',
                        range: startRange,
                        message: ''
                    }
                ]
            })).toEqual([]);
        });
        it('if diagnostic is error', async () => {
            (await expectCodeActionFor('', {
                diagnostics: [
                    {
                        source: 'svelte',
                        range: startRange,
                        message: '',
                        severity: vscode_languageserver_1.DiagnosticSeverity.Error
                    }
                ]
            })).toEqual([]);
        });
    });
    describe('It should provide svelte anchor missing attribute code actions', () => {
        const svelteAnchorMissingAttributeCodeAction = 'svelte-anchor-missing-attribute-code-action.svelte';
        it('Should provide svelte anchor add missing attribute', async () => {
            (await expectCodeActionFor(svelteAnchorMissingAttributeCodeAction, {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'security-anchor-rel-noreferrer',
                        range: vscode_languageserver_1.Range.create({ line: 0, character: 0 }, { line: 0, character: 55 }),
                        message: 'Security: Anchor with "target=_blank" should have rel attribute containing the value "noreferrer"',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: ' rel="noreferrer"',
                                        range: {
                                            end: {
                                                character: 44,
                                                line: 0
                                            },
                                            start: {
                                                character: 44,
                                                line: 0
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteAnchorMissingAttributeCodeAction),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Add missing attribute rel="noreferrer"',
                    kind: 'quickfix'
                },
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `<!-- svelte-ignore security-anchor-rel-noreferrer -->${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 0
                                            },
                                            start: {
                                                character: 0,
                                                line: 0
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteAnchorMissingAttributeCodeAction),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable security-anchor-rel-noreferrer for this line',
                    kind: 'quickfix'
                }
            ]);
        });
        const svelteAnchorMissingAttributeCodeActionRel = 'svelte-anchor-missing-attribute-code-action-rel.svelte';
        it('Should not duplicate rel attribute', async () => {
            (await expectCodeActionFor(svelteAnchorMissingAttributeCodeActionRel, {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'security-anchor-rel-noreferrer',
                        range: vscode_languageserver_1.Range.create({ line: 0, character: 0 }, { line: 0, character: 70 }),
                        message: 'Security: Anchor with "target=_blank" should have rel attribute containing the value "noreferrer"',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: ' noreferrer',
                                        range: {
                                            end: {
                                                character: 58,
                                                line: 0
                                            },
                                            start: {
                                                character: 58,
                                                line: 0
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteAnchorMissingAttributeCodeActionRel),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Add missing attribute rel="noreferrer"',
                    kind: 'quickfix'
                },
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `<!-- svelte-ignore security-anchor-rel-noreferrer -->${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 0
                                            },
                                            start: {
                                                character: 0,
                                                line: 0
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteAnchorMissingAttributeCodeActionRel),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable security-anchor-rel-noreferrer for this line',
                    kind: 'quickfix'
                }
            ]);
        });
    });
    describe('It should provide svelte ignore code actions ', () => {
        const svelteIgnoreCodeAction = 'svelte-ignore-code-action.svelte';
        it('should provide ignore comment', async () => {
            (await expectCodeActionFor(svelteIgnoreCodeAction, {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'a11y-missing-attribute',
                        range: vscode_languageserver_1.Range.create({ line: 0, character: 0 }, { line: 0, character: 6 }),
                        message: '',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `<!-- svelte-ignore a11y-missing-attribute -->${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 0
                                            },
                                            start: {
                                                character: 0,
                                                line: 0
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteIgnoreCodeAction),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable a11y-missing-attribute for this line',
                    kind: 'quickfix'
                }
            ]);
        });
        it('should provide ignore comment with indent', async () => {
            (await expectCodeActionFor(svelteIgnoreCodeAction, {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'a11y-missing-attribute',
                        range: vscode_languageserver_1.Range.create({ line: 3, character: 4 }, { line: 3, character: 11 }),
                        message: '',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `${' '.repeat(4)}<!-- svelte-ignore a11y-missing-attribute -->${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 3
                                            },
                                            start: {
                                                character: 0,
                                                line: 3
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteIgnoreCodeAction),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable a11y-missing-attribute for this line',
                    kind: 'quickfix'
                }
            ]);
        });
        it('should provide ignore comment with indent of parent tag', async () => {
            (await expectCodeActionFor(svelteIgnoreCodeAction, {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'a11y-invalid-attribute',
                        range: vscode_languageserver_1.Range.create({ line: 6, character: 8 }, { line: 6, character: 15 }),
                        message: '',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `${' '.repeat(4)}<!-- svelte-ignore a11y-invalid-attribute -->${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 5
                                            },
                                            start: {
                                                character: 0,
                                                line: 5
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteIgnoreCodeAction),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable a11y-invalid-attribute for this line',
                    kind: 'quickfix'
                }
            ]);
        });
        it('should provide ignore comment in script tags', async () => {
            (await expectCodeActionFor(svelteIgnoreCodeAction, {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'state_referenced_locally',
                        range: vscode_languageserver_1.Range.create({ line: 13, character: 9 }, { line: 13, character: 14 }),
                        message: '',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `\t// svelte-ignore state_referenced_locally${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 13
                                            },
                                            start: {
                                                character: 0,
                                                line: 13
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteIgnoreCodeAction),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable state_referenced_locally for this line',
                    kind: 'quickfix'
                }
            ]);
        });
        it('should properly place svelte ignore code actions when the html is on both sides of the script tag', async () => {
            (await expectCodeActionFor('svelte-ignore-correct-script-placement.svelte', {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'state_referenced_locally',
                        range: vscode_languageserver_1.Range.create({ line: 7, character: 16 }, { line: 7, character: 17 }),
                        message: '',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `\t// svelte-ignore state_referenced_locally${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 7
                                            },
                                            start: {
                                                character: 0,
                                                line: 7
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri('svelte-ignore-correct-script-placement.svelte'),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable state_referenced_locally for this line',
                    kind: 'quickfix'
                }
            ]);
        });
    });
    describe('It should provide svelte ignore code actions (TypeScript)', () => {
        const svelteIgnoreCodeAction = 'svelte-ignore-code-action-ts.svelte';
        it('should provide ignore comment', async () => {
            (await expectCodeActionFor(svelteIgnoreCodeAction, {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'a11y-missing-attribute',
                        range: vscode_languageserver_1.Range.create({ line: 7, character: 0 }, { line: 7, character: 6 }),
                        message: '',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `<!-- svelte-ignore a11y-missing-attribute -->${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 7
                                            },
                                            start: {
                                                character: 0,
                                                line: 7
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteIgnoreCodeAction),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable a11y-missing-attribute for this line',
                    kind: 'quickfix'
                }
            ]);
        });
        it('should provide ignore comment with indent', async () => {
            (await expectCodeActionFor(svelteIgnoreCodeAction, {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'a11y-missing-attribute',
                        range: vscode_languageserver_1.Range.create({ line: 10, character: 4 }, { line: 10, character: 11 }),
                        message: '',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `${' '.repeat(4)}<!-- svelte-ignore a11y-missing-attribute -->${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 10
                                            },
                                            start: {
                                                character: 0,
                                                line: 10
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteIgnoreCodeAction),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable a11y-missing-attribute for this line',
                    kind: 'quickfix'
                }
            ]);
        });
        it('should provide ignore comment with indent of parent tag', async () => {
            (await expectCodeActionFor(svelteIgnoreCodeAction, {
                diagnostics: [
                    {
                        severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
                        code: 'a11y-invalid-attribute',
                        range: vscode_languageserver_1.Range.create({ line: 13, character: 8 }, { line: 13, character: 15 }),
                        message: '',
                        source: 'svelte'
                    }
                ]
            })).toEqual([
                {
                    edit: {
                        documentChanges: [
                            {
                                edits: [
                                    {
                                        newText: `${' '.repeat(4)}<!-- svelte-ignore a11y-invalid-attribute -->${os_1.EOL}`,
                                        range: {
                                            end: {
                                                character: 0,
                                                line: 12
                                            },
                                            start: {
                                                character: 0,
                                                line: 12
                                            }
                                        }
                                    }
                                ],
                                textDocument: {
                                    uri: getUri(svelteIgnoreCodeAction),
                                    version: null
                                }
                            }
                        ]
                    },
                    title: '(svelte) Disable a11y-invalid-attribute for this line',
                    kind: 'quickfix'
                }
            ]);
        });
    });
    describe('#extractComponent', async () => {
        const scriptContent = `<script>
        const bla = true;
        </script>`;
        const styleContent = '<style>p{color: blue}</style>';
        const content = `
        ${scriptContent}
        <p>something else</p>
        <p>extract me</p>
        ${styleContent}`;
        const doc = new SvelteDocument_1.SvelteDocument(new documents_1.Document('someUrl', content));
        async function extractComponent(filePath, range) {
            return (0, getRefactorings_1.executeRefactoringCommand)(doc, getRefactorings_1.extractComponentCommand, [
                '',
                {
                    filePath,
                    range,
                    uri: ''
                }
            ]);
        }
        async function shouldExtractComponent(path) {
            const range = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(5, 8), vscode_languageserver_1.Position.create(5, 25));
            const result = await extractComponent(path, range);
            assert.deepStrictEqual(result, {
                documentChanges: [
                    vscode_languageserver_1.TextDocumentEdit.create(vscode_languageserver_1.OptionalVersionedTextDocumentIdentifier.create('someUrl', null), [
                        vscode_languageserver_1.TextEdit.replace(range, '<NewComp></NewComp>'),
                        vscode_languageserver_1.TextEdit.insert(doc.script?.startPos || vscode_languageserver_1.Position.create(0, 0), "\n  import NewComp from './NewComp.svelte';\n")
                    ]),
                    vscode_languageserver_1.CreateFile.create('file:///NewComp.svelte', { overwrite: true }),
                    vscode_languageserver_1.TextDocumentEdit.create(vscode_languageserver_1.OptionalVersionedTextDocumentIdentifier.create('file:///NewComp.svelte', null), [
                        vscode_languageserver_1.TextEdit.insert(vscode_languageserver_1.Position.create(0, 0), `${scriptContent}\n\n<p>extract me</p>\n\n${styleContent}\n\n`)
                    ])
                ]
            });
        }
        it('should extract component (no .svelte at the end)', async () => {
            await shouldExtractComponent('./NewComp');
        });
        it('should extract component (no .svelte at the end, no relative path)', async () => {
            await shouldExtractComponent('NewComp');
        });
        it('should extract component (.svelte at the end, no relative path', async () => {
            await shouldExtractComponent('NewComp.svelte');
        });
        it('should extract component (.svelte at the end, relative path)', async () => {
            await shouldExtractComponent('./NewComp.svelte');
        });
        it('should return "Invalid selection range"', async () => {
            const range = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(6, 8), vscode_languageserver_1.Position.create(6, 25));
            const result = await extractComponent('Bla', range);
            assert.deepStrictEqual(result, 'Invalid selection range');
        });
        it('should update relative imports', async () => {
            const content = `<script>
            import OtherComponent from './OtherComponent.svelte';
            import {test} from '../test';
            </script>
            toExtract
            <style>
            @import './style.css';
            </style>`;
            const existingFileUri = (0, utils_1.pathToUrl)('C:/path/File.svelte');
            const doc = new SvelteDocument_1.SvelteDocument(new documents_1.Document(existingFileUri, content));
            const range = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(4, 12), vscode_languageserver_1.Position.create(4, 21));
            const result = await (0, getRefactorings_1.executeRefactoringCommand)(doc, getRefactorings_1.extractComponentCommand, [
                '',
                {
                    filePath: '../NewComp',
                    range,
                    uri: ''
                }
            ]);
            const newFileUri = (0, utils_1.pathToUrl)('C:/NewComp.svelte');
            assert.deepStrictEqual(result, {
                documentChanges: [
                    vscode_languageserver_1.TextDocumentEdit.create(vscode_languageserver_1.OptionalVersionedTextDocumentIdentifier.create(existingFileUri, null), [
                        vscode_languageserver_1.TextEdit.replace(range, '<NewComp></NewComp>'),
                        vscode_languageserver_1.TextEdit.insert(doc.script?.startPos || vscode_languageserver_1.Position.create(0, 0), "\n  import NewComp from '../NewComp.svelte';\n")
                    ]),
                    vscode_languageserver_1.CreateFile.create(newFileUri, { overwrite: true }),
                    vscode_languageserver_1.TextDocumentEdit.create(vscode_languageserver_1.OptionalVersionedTextDocumentIdentifier.create(newFileUri, null), [
                        vscode_languageserver_1.TextEdit.insert(vscode_languageserver_1.Position.create(0, 0), `<script>
            import OtherComponent from './path/OtherComponent.svelte';
            import {test} from './test';
            </script>\n\ntoExtract\n\n<style>
            @import './path/style.css';
            </style>\n\n`)
                    ])
                ]
            });
        });
    });
});
//# sourceMappingURL=getCodeAction.test.js.map