"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 path = __importStar(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 RenameProvider_1 = require("../../../../src/plugins/typescript/features/RenameProvider");
const LSAndTSDocResolver_1 = require("../../../../src/plugins/typescript/LSAndTSDocResolver");
const service_1 = require("../../../../src/plugins/typescript/service");
const utils_1 = require("../../../../src/utils");
const testDir = path.join(__dirname, '..');
describe('RenameProvider', () => {
    function getFullPath(filename) {
        return path.join(testDir, 'testfiles', 'rename', filename);
    }
    function getUri(filename) {
        return (0, utils_1.pathToUrl)(getFullPath(filename));
    }
    async function setup() {
        const configManager = new ls_config_1.LSConfigManager();
        const docManager = new documents_1.DocumentManager((textDocument) => new documents_1.Document(textDocument.uri, textDocument.text));
        const lsAndTsDocResolver = new LSAndTSDocResolver_1.LSAndTSDocResolver(docManager, [(0, utils_1.pathToUrl)(testDir)], configManager);
        const provider = new RenameProvider_1.RenameProviderImpl(lsAndTsDocResolver, configManager);
        const renameDoc1 = await openDoc('rename.svelte');
        const renameDoc2 = await openDoc('rename2.svelte');
        const renameDoc3 = await openDoc('rename3.svelte');
        const renameDoc4 = await openDoc('rename4.svelte');
        const renameDoc5 = await openDoc('rename5.svelte');
        const renameDoc6 = await openDoc('rename6.svelte');
        const renameDocIgnoreGenerated = await openDoc('rename-ignore-generated.svelte');
        const renameDocSlotEventsImporter = await openDoc('rename-slot-events-importer.svelte');
        const renameDocPropWithSlotEvents = await openDoc('rename-prop-with-slot-events.svelte');
        const renameDocShorthand = await openDoc('rename-shorthand.svelte');
        const renameSlotLet = await openDoc('rename-slot-let.svelte');
        return {
            provider,
            renameDoc1,
            renameDoc2,
            renameDoc3,
            renameDoc4,
            renameDoc5,
            renameDoc6,
            renameDocIgnoreGenerated,
            renameDocSlotEventsImporter,
            renameDocPropWithSlotEvents,
            renameDocShorthand,
            renameSlotLet,
            docManager
        };
        async function openDoc(filename) {
            const filePath = getFullPath(filename);
            const doc = docManager.openDocument({
                uri: (0, utils_1.pathToUrl)(filePath),
                text: typescript_1.default.sys.readFile(filePath) || ''
            });
            // Do this to make the file known to the ts language service
            await provider.rename(doc, vscode_languageserver_1.Position.create(0, 0), '');
            return doc;
        }
    }
    it('should rename variable that is scoped to component only', async () => {
        const { provider, renameDoc1 } = await setup();
        const result = await provider.rename(renameDoc1, vscode_languageserver_1.Position.create(2, 15), 'newName');
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 8,
                                line: 2
                            },
                            end: {
                                character: 17,
                                line: 2
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 1,
                                line: 5
                            },
                            end: {
                                character: 10,
                                line: 5
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 5,
                                line: 6
                            },
                            end: {
                                character: 14,
                                line: 6
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 8,
                                line: 8
                            },
                            end: {
                                character: 17,
                                line: 8
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 7,
                                line: 10
                            },
                            end: {
                                character: 16,
                                line: 10
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 15,
                                line: 12
                            },
                            end: {
                                character: 24,
                                line: 12
                            }
                        }
                    }
                ]
            }
        });
    });
    const expectedEditsForPropRename = {
        changes: {
            [getUri('rename.svelte')]: [
                {
                    newText: 'newName',
                    range: {
                        start: {
                            character: 15,
                            line: 1
                        },
                        end: {
                            character: 27,
                            line: 1
                        }
                    }
                },
                {
                    newText: 'newName',
                    range: {
                        start: {
                            character: 1,
                            line: 14
                        },
                        end: {
                            character: 13,
                            line: 14
                        }
                    }
                }
            ],
            [getUri('rename2.svelte')]: [
                {
                    newText: 'newName',
                    range: {
                        start: {
                            character: 8,
                            line: 5
                        },
                        end: {
                            character: 20,
                            line: 5
                        }
                    }
                }
            ]
        }
    };
    it('should do rename of prop of component A in component A', async () => {
        const { provider, renameDoc1 } = await setup();
        const result = await provider.rename(renameDoc1, vscode_languageserver_1.Position.create(1, 25), 'newName');
        assert.deepStrictEqual(result, expectedEditsForPropRename);
    });
    it('should do rename of prop of component A in component B', async () => {
        const { provider, renameDoc2 } = await setup();
        const result = await provider.rename(renameDoc2, vscode_languageserver_1.Position.create(5, 10), 'newName');
        assert.deepStrictEqual(result, expectedEditsForPropRename);
    });
    it('should not allow rename of intrinsic attribute', async () => {
        const { provider, renameDoc2 } = await setup();
        const prepareResult = await provider.prepareRename(renameDoc2, vscode_languageserver_1.Position.create(7, 7));
        const renameResult = await provider.rename(renameDoc2, vscode_languageserver_1.Position.create(7, 7), 'newName');
        assert.deepStrictEqual(prepareResult, null);
        assert.deepStrictEqual(renameResult, null);
    });
    it('should do rename of prop without type of component A in component A', async () => {
        const { provider, renameDoc3 } = await setup();
        const result = await provider.rename(renameDoc3, vscode_languageserver_1.Position.create(1, 25), 'newName');
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename3.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 15,
                                line: 1
                            },
                            end: {
                                character: 33,
                                line: 1
                            }
                        }
                    }
                ],
                [getUri('rename2.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 9,
                                line: 6
                            },
                            end: {
                                character: 27,
                                line: 6
                            }
                        }
                    }
                ]
            }
        });
    });
    it('should do rename of prop without type of component A in component A that is used with shorthands in component B', async () => {
        const { provider, renameDoc3 } = await setup();
        const result = await provider.rename(renameDoc3, vscode_languageserver_1.Position.create(2, 20), 'newName');
        console.log(JSON.stringify(result, null, 3));
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename3.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                line: 2,
                                character: 15
                            },
                            end: {
                                line: 2,
                                character: 21
                            }
                        }
                    }
                ],
                [getUri('rename-shorthand.svelte')]: [
                    {
                        newText: 'newName={props2}',
                        range: {
                            start: {
                                line: 6,
                                character: 12
                            },
                            end: {
                                line: 6,
                                character: 18
                            }
                        }
                    },
                    {
                        newText: 'newName={props2',
                        range: {
                            start: {
                                line: 7,
                                character: 7
                            },
                            end: {
                                line: 7,
                                character: 14
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                line: 8,
                                character: 7
                            },
                            end: {
                                line: 8,
                                character: 13
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                line: 9,
                                character: 7
                            },
                            end: {
                                line: 9,
                                character: 13
                            }
                        }
                    }
                ]
            }
        });
    });
    it('should do rename of prop without type of component A in component B', async () => {
        const { provider, renameDoc2 } = await setup();
        const result = await provider.rename(renameDoc2, vscode_languageserver_1.Position.create(6, 11), 'newName');
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename2.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 9,
                                line: 6
                            },
                            end: {
                                character: 27,
                                line: 6
                            }
                        }
                    }
                ],
                [getUri('rename3.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 15,
                                line: 1
                            },
                            end: {
                                character: 33,
                                line: 1
                            }
                        }
                    }
                ]
            }
        });
    });
    it('should do rename of svelte component', async () => {
        const { provider, renameDoc4 } = await setup();
        const result = await provider.rename(renameDoc4, vscode_languageserver_1.Position.create(1, 12), 'ChildNew');
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename4.svelte')]: [
                    {
                        newText: 'ChildNew',
                        range: {
                            start: {
                                line: 1,
                                character: 11
                            },
                            end: {
                                line: 1,
                                character: 16
                            }
                        }
                    },
                    {
                        newText: 'ChildNew',
                        range: {
                            start: {
                                line: 7,
                                character: 5
                            },
                            end: {
                                line: 7,
                                character: 10
                            }
                        }
                    },
                    {
                        newText: 'ChildNew',
                        range: {
                            start: {
                                line: 8,
                                character: 5
                            },
                            end: {
                                line: 8,
                                character: 10
                            }
                        }
                    }
                ]
            }
        });
    });
    describe('should allow rename of $store', () => {
        async function do$storeRename(pos) {
            var _a;
            const { provider, renameDoc5 } = await setup();
            const result = await provider.rename(renameDoc5, pos, 'store1');
            (_a = result === null || result === void 0 ? void 0 : result.changes) === null || _a === void 0 ? void 0 : _a[getUri('rename5.svelte')].sort((c1, c2) => c1.range.start.line - c2.range.start.line);
            assert.deepStrictEqual(result, {
                changes: {
                    [getUri('rename5.svelte')]: [
                        {
                            newText: 'store1',
                            range: {
                                start: {
                                    line: 1,
                                    character: 8
                                },
                                end: {
                                    line: 1,
                                    character: 13
                                }
                            }
                        },
                        {
                            newText: '$store1',
                            range: {
                                start: {
                                    line: 2,
                                    character: 4
                                },
                                end: {
                                    line: 2,
                                    character: 10
                                }
                            }
                        },
                        {
                            newText: '$store1',
                            range: {
                                start: {
                                    line: 3,
                                    character: 7
                                },
                                end: {
                                    line: 3,
                                    character: 13
                                }
                            }
                        },
                        {
                            newText: '$store: $store1',
                            range: {
                                start: {
                                    line: 4,
                                    character: 18
                                },
                                end: {
                                    line: 4,
                                    character: 24
                                }
                            }
                        },
                        {
                            newText: '$store1',
                            range: {
                                start: {
                                    line: 7,
                                    character: 1
                                },
                                end: {
                                    line: 7,
                                    character: 7
                                }
                            }
                        },
                        {
                            newText: '$store1',
                            range: {
                                start: {
                                    line: 8,
                                    character: 5
                                },
                                end: {
                                    line: 8,
                                    character: 11
                                }
                            }
                        }
                    ]
                }
            });
        }
        it('from definition', async () => {
            await do$storeRename(vscode_languageserver_1.Position.create(1, 10));
        });
        it('from usage within script', async () => {
            await do$storeRename(vscode_languageserver_1.Position.create(3, 10));
        });
    });
    it('should allow rename of variable', async () => {
        const { provider, renameDoc1 } = await setup();
        const result = await provider.prepareRename(renameDoc1, vscode_languageserver_1.Position.create(1, 25));
        assert.deepStrictEqual(result, {
            start: {
                character: 15,
                line: 1
            },
            end: {
                character: 27,
                line: 1
            }
        });
    });
    it('should not allow rename of html element', async () => {
        const { provider, renameDoc1 } = await setup();
        const result = await provider.prepareRename(renameDoc1, vscode_languageserver_1.Position.create(12, 1));
        assert.deepStrictEqual(result, null);
    });
    it('should not allow rename of html attribute', async () => {
        const { provider, renameDoc1 } = await setup();
        const result = await provider.prepareRename(renameDoc1, vscode_languageserver_1.Position.create(12, 5));
        assert.deepStrictEqual(result, null);
    });
    it('should rename with prefix', async () => {
        const { provider, renameDoc6 } = await setup();
        const result = await provider.rename(renameDoc6, vscode_languageserver_1.Position.create(3, 9), 'newName');
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename6.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                character: 8,
                                line: 3
                            },
                            end: {
                                character: 11,
                                line: 3
                            }
                        }
                    },
                    {
                        newText: 'foo: newName',
                        range: {
                            start: {
                                character: 16,
                                line: 4
                            },
                            end: {
                                character: 19,
                                line: 4
                            }
                        }
                    },
                    {
                        newText: 'foo: newName',
                        range: {
                            start: {
                                character: 18,
                                line: 7
                            },
                            end: {
                                character: 21,
                                line: 7
                            }
                        }
                    }
                ]
            }
        });
    });
    it('should rename and ignore generated', async () => {
        const { provider, renameDocIgnoreGenerated } = await setup();
        const result = await provider.rename(renameDocIgnoreGenerated, vscode_languageserver_1.Position.create(1, 8), 'newName');
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename-ignore-generated.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            end: {
                                character: 9,
                                line: 1
                            },
                            start: {
                                character: 8,
                                line: 1
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            end: {
                                character: 6,
                                line: 5
                            },
                            start: {
                                character: 5,
                                line: 5
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            end: {
                                character: 21,
                                line: 7
                            },
                            start: {
                                character: 20,
                                line: 7
                            }
                        }
                    }
                ]
            }
        });
    });
    it('rename prop correctly when events/slots present', async () => {
        const { provider, renameDocPropWithSlotEvents } = await setup();
        const result = await provider.rename(renameDocPropWithSlotEvents, vscode_languageserver_1.Position.create(3, 15), 'newName');
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename-prop-with-slot-events.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            end: {
                                character: 17,
                                line: 3
                            },
                            start: {
                                character: 13,
                                line: 3
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            end: {
                                character: 17,
                                line: 8
                            },
                            start: {
                                character: 13,
                                line: 8
                            }
                        }
                    }
                ],
                [getUri('rename-slot-events-importer.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            end: {
                                character: 7,
                                line: 4
                            },
                            start: {
                                character: 3,
                                line: 4
                            }
                        }
                    }
                ]
            }
        });
    });
    it('can rename shorthand props without breaking value-passing', async () => {
        await testShorthand(vscode_languageserver_1.Position.create(3, 16));
    });
    it('can rename shorthand props without breaking value-passing (triggers from shorthand)', async () => {
        await testShorthand(vscode_languageserver_1.Position.create(7, 9));
    });
    async function testShorthand(position) {
        const { provider, renameDocShorthand } = await setup();
        const result = await provider.rename(renameDocShorthand, position, 'newName');
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename-shorthand.svelte')]: [
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                line: 3,
                                character: 15
                            },
                            end: {
                                line: 3,
                                character: 21
                            }
                        }
                    },
                    {
                        newText: 'props2={newName}',
                        range: {
                            start: {
                                line: 6,
                                character: 12
                            },
                            end: {
                                line: 6,
                                character: 18
                            }
                        }
                    },
                    {
                        newText: 'props2={newName}',
                        range: {
                            start: {
                                line: 7,
                                character: 7
                            },
                            end: {
                                line: 7,
                                character: 15
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                line: 8,
                                character: 15
                            },
                            end: {
                                line: 8,
                                character: 21
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            start: {
                                line: 9,
                                character: 15
                            },
                            end: {
                                line: 9,
                                character: 21
                            }
                        }
                    }
                ]
            }
        });
    }
    it('can rename slot let to an alias', async () => {
        const { provider, renameSlotLet } = await setup();
        const result = await provider.rename(renameSlotLet, vscode_languageserver_1.Position.create(4, 7), 'newName');
        assert.deepStrictEqual(result, {
            changes: {
                [getUri('rename-slot-let.svelte')]: [
                    {
                        newText: 'aSlot={newName}',
                        range: {
                            end: {
                                character: 12,
                                line: 4
                            },
                            start: {
                                character: 7,
                                line: 4
                            }
                        }
                    },
                    {
                        newText: 'newName',
                        range: {
                            end: {
                                character: 26,
                                line: 4
                            },
                            start: {
                                character: 21,
                                line: 4
                            }
                        }
                    }
                ]
            }
        });
    });
    after(() => {
        // Hacky, but it works. Needed due to testing both new and old transformation
        (0, service_1.__resetCache)();
    });
});
//# sourceMappingURL=RenameProvider.test.js.map