• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.textStorage {
2    describe("unittests:: tsserver:: Text storage", () => {
3        const f = {
4            path: "/a/app.ts",
5            content: `
6                let x = 1;
7                let y = 2;
8                function bar(a: number) {
9                    return a + 1;
10                }`
11        };
12
13        function getDummyScriptInfo(fileName: string) {
14            return { fileName, closeSourceMapFileWatcher: noop } as server.ScriptInfo;
15        }
16
17        it("text based storage should be have exactly the same as script version cache", () => {
18
19            const host = projectSystem.createServerHost([f]);
20            // Since script info is not used in these tests, just cheat by passing undefined
21            const ts1 = new server.TextStorage(host, getDummyScriptInfo(server.asNormalizedPath(f.path)));
22            const ts2 = new server.TextStorage(host, getDummyScriptInfo(server.asNormalizedPath(f.path)));
23
24            ts1.useScriptVersionCache_TestOnly();
25            ts2.useText();
26
27            const lineMap = computeLineStarts(f.content);
28
29            for (let line = 0; line < lineMap.length; line++) {
30                const start = lineMap[line];
31                const end = line === lineMap.length - 1 ? f.path.length : lineMap[line + 1];
32
33                for (let offset = 0; offset < end - start; offset++) {
34                    const pos1 = ts1.lineOffsetToPosition(line + 1, offset + 1);
35                    const pos2 = ts2.lineOffsetToPosition(line + 1, offset + 1);
36                    assert.strictEqual(pos1, pos2, `lineOffsetToPosition ${line + 1}-${offset + 1}: expected ${pos1} to equal ${pos2}`);
37                }
38
39                const {start: start1, length: length1 } = ts1.lineToTextSpan(line);
40                const {start: start2, length: length2 } = ts2.lineToTextSpan(line);
41                assert.strictEqual(start1, start2, `lineToTextSpan ${line}::start:: expected ${start1} to equal ${start2}`);
42                assert.strictEqual(length1, length2, `lineToTextSpan ${line}::length:: expected ${length1} to equal ${length2}`);
43            }
44
45            for (let pos = 0; pos < f.content.length; pos++) {
46                const { line: line1, offset: offset1 } = ts1.positionToLineOffset(pos);
47                const { line: line2, offset: offset2 } = ts2.positionToLineOffset(pos);
48                assert.strictEqual(line1, line2, `positionToLineOffset ${pos}::line:: expected ${line1} to equal ${line2}`);
49                assert.strictEqual(offset1, offset2, `positionToLineOffset ${pos}::offset:: expected ${offset1} to equal ${offset2}`);
50            }
51        });
52
53        it("should switch to script version cache if necessary", () => {
54            const host = projectSystem.createServerHost([f]);
55            // Since script info is not used in these tests, just cheat by passing undefined
56            const ts1 = new server.TextStorage(host, getDummyScriptInfo(server.asNormalizedPath(f.path)));
57
58            ts1.getSnapshot();
59            assert.isFalse(ts1.hasScriptVersionCache_TestOnly(), "should not have script version cache - 1");
60
61            ts1.edit(0, 5, "   ");
62            assert.isTrue(ts1.hasScriptVersionCache_TestOnly(), "have script version cache - 1");
63
64            ts1.useText();
65            assert.isFalse(ts1.hasScriptVersionCache_TestOnly(), "should not have script version cache - 2");
66
67            ts1.getAbsolutePositionAndLineText(0);
68            assert.isTrue(ts1.hasScriptVersionCache_TestOnly(), "have script version cache - 2");
69        });
70
71        it("should be able to return the file size immediately after construction", () => {
72            const host = projectSystem.createServerHost([f]);
73            // Since script info is not used in these tests, just cheat by passing undefined
74            const ts1 = new server.TextStorage(host, getDummyScriptInfo(server.asNormalizedPath(f.path)));
75
76            assert.strictEqual(f.content.length, ts1.getTelemetryFileSize());
77        });
78
79        it("should be able to return the file size when backed by text", () => {
80            const host = projectSystem.createServerHost([f]);
81            // Since script info is not used in these tests, just cheat by passing undefined
82            const ts1 = new server.TextStorage(host, getDummyScriptInfo(server.asNormalizedPath(f.path)));
83
84            ts1.useText(f.content);
85            assert.isFalse(ts1.hasScriptVersionCache_TestOnly());
86
87            assert.strictEqual(f.content.length, ts1.getTelemetryFileSize());
88        });
89
90        it("should be able to return the file size when backed by a script version cache", () => {
91            const host = projectSystem.createServerHost([f]);
92            // Since script info is not used in these tests, just cheat by passing undefined
93            const ts1 = new server.TextStorage(host, getDummyScriptInfo(server.asNormalizedPath(f.path)));
94
95            ts1.useScriptVersionCache_TestOnly();
96            assert.isTrue(ts1.hasScriptVersionCache_TestOnly());
97
98            assert.strictEqual(f.content.length, ts1.getTelemetryFileSize());
99        });
100
101        it("should be able to return the file size when a JS file is too large to load into text", () => {
102            const largeFile = {
103                path: "/a/large.js",
104                content: " ".repeat(server.maxFileSize + 1)
105            };
106
107            const host = projectSystem.createServerHost([largeFile]);
108
109            // The large-file handling requires a ScriptInfo with a containing project
110            const projectService = projectSystem.createProjectService(host);
111            projectService.openClientFile(largeFile.path);
112            const scriptInfo = projectService.getScriptInfo(largeFile.path);
113
114            const ts1 = new server.TextStorage(host, scriptInfo!);
115
116            assert.isTrue(ts1.reloadFromDisk());
117            assert.isFalse(ts1.hasScriptVersionCache_TestOnly());
118
119            assert.strictEqual(largeFile.content.length, ts1.getTelemetryFileSize());
120        });
121
122        it("should return the file size without reloading the file", () => {
123            const oldText = "hello";
124            const newText = "goodbye";
125
126            const changingFile = {
127                path: "/a/changing.ts",
128                content: oldText
129            };
130
131            const host = projectSystem.createServerHost([changingFile]);
132            // Since script info is not used in these tests, just cheat by passing undefined
133            const ts1 = new server.TextStorage(host, getDummyScriptInfo(server.asNormalizedPath(changingFile.path)));
134
135            assert.isTrue(ts1.reloadFromDisk());
136
137            // Refresh the file and notify TextStorage
138            host.writeFile(changingFile.path, newText);
139            ts1.delayReloadFromFileIntoText();
140
141            assert.strictEqual(oldText.length, ts1.getTelemetryFileSize());
142
143            assert.isTrue(ts1.reloadWithFileText());
144
145            assert.strictEqual(newText.length, ts1.getTelemetryFileSize());
146        });
147    });
148}
149