Esempio n. 1
0
        public async Task CodeContentTrackingAsync()
        {
            var fileSize        = 10;
            var filename        = inputGenerator.GenerateRandomFile(fileSize, null, true);
            var expectedContent = TestUtils.GetContent(filename);
            var openParams      = TestUtils.GetOpenFileParams(filename);

            await SetupAsync();

            await rpc.InvokeWithParameterObjectAsync <Task>(Methods.TextDocumentDidOpen.Name, openParams);

            for (var testRep = 0; testRep < 20; ++testRep)
            {
                var edits = inputGenerator.MakeRandomEdits(50, ref expectedContent, fileSize, true);

                Task[] processing = new Task[edits.Length];
                for (var i = 0; i < edits.Length; ++i)
                {
                    processing[i] = rpc.InvokeWithParameterObjectAsync <Task>(Methods.TextDocumentDidChange.Name, TestUtils.GetChangedFileParams(filename, new[] { edits[i] }));
                }

                for (var i = edits.Length - 1; i >= 0; --i)
                {
                    await processing[i];
                }
                var trackedContent = await this.GetFileContentInMemoryAsync(filename);

                var expected = Builder.JoinLines(expectedContent.ToArray());
                var got      = Builder.JoinLines(trackedContent);
                Assert.IsNotNull(trackedContent);
                Assert.AreEqual(expectedContent.Count(), trackedContent.Count(), $"expected: \n{expected} \ngot: \n{got}");
                Assert.AreEqual(expected, got);
            }
        }
Esempio n. 2
0
        internal static void ApplyEdit(TextDocumentContentChangeEvent change, ref List <string> content)
        {
            if (!content.Any())
            {
                throw new ArgumentException("the given content has to have at least on line");
            }

            Assert.IsTrue(IsValidRange(change.Range) && change.Text != null);
            Assert.IsTrue(change.Range.End.Line < content.Count());
            Assert.IsTrue(change.Range.Start.Character <= content[change.Range.Start.Line].Length);
            Assert.IsTrue(change.Range.End.Character <= content[change.Range.End.Line].Length);

            var(startLine, startChar) = (change.Range.Start.Line, change.Range.Start.Character);
            var(endLine, endChar)     = (change.Range.End.Line, change.Range.End.Character);

            var newText = string.Concat(content[startLine].Substring(0, startChar), change.Text, content[endLine].Substring(endChar));

            if (startLine > 0)
            {
                newText = content[--startLine] + newText;
            }
            if (endLine + 1 < content.Count)
            {
                newText = newText + content[++endLine];
            }
            var lineChanges = Builder.SplitLines(newText);

            if (lineChanges.Length == 0 || (endLine + 1 == content.Count() && Builder.EndOfLine.Match(lineChanges.Last()).Success))
            {
                lineChanges = lineChanges.Concat(new string[] { string.Empty }).ToArray();
            }

            content.RemoveRange(startLine, endLine - startLine + 1);
            content.InsertRange(startLine, lineChanges);
        }
Esempio n. 3
0
        // does not modify range
        internal static int GetRangeLength(VisualStudio.LanguageServer.Protocol.Range range, IReadOnlyList <string> content)
        {
            Assert.IsTrue(Builder.IsValidRange(range));
            if (range.Start.Line == range.End.Line)
            {
                return(range.End.Character - range.Start.Character);
            }

            var changeLength = content[range.Start.Line].Length - range.Start.Character;

            for (var line = range.Start.Line + 1; line < range.End.Line; ++line)
            {
                changeLength += content[line].Length;
            }
            return(changeLength + range.End.Character);
        }
Esempio n. 4
0
        private Range GetRandomRange(IReadOnlyList <string> content)
        {
            var(startLine, endLine) = (rnd.Next(0, content.Count), rnd.Next(0, content.Count));
            var(startChar, endChar) = (rnd.Next(0, content[startLine].Length + 1), rnd.Next(0, content[endLine].Length + 1));

            ((startLine, startChar), (endLine, endChar)) =
                startLine <= endLine ?
                ((startLine, startChar), (endLine, endChar)) :
                ((endLine, endChar), (startLine, startChar));
            if (startLine == endLine && startChar > endChar)
            {
                (startChar, endChar) = (endChar, startChar);
            }

            var range = new Range {
                Start = new Position(startLine, startChar), End = new Position(endLine, endChar)
            };

            Assert.IsTrue(Builder.IsValidRange(range));
            return(range);
        }
Esempio n. 5
0
        public async Task SaveFileAsync()
        {
            var fileSize = 10;
            var filename = inputGenerator.GenerateRandomFile(fileSize, null);
            var content  = File.ReadAllText(Path.GetFullPath(filename));

            await SetupAsync();

            // verify that safe notification can be sent immediately after sending the open notification (even if the latter has not yet finished processing)

            var openFileTask = rpc.InvokeWithParameterObjectAsync <Task>(Methods.TextDocumentDidOpen.Name, TestUtils.GetOpenFileParams(filename));
            await rpc.InvokeWithParameterObjectAsync <Task>(Methods.TextDocumentDidSave.Name, TestUtils.GetSaveFileParams(filename, content));

            // check that the file content is indeed updated on save, according to the passed parameter

            var newContent = String.Join(Environment.NewLine, inputGenerator.GetRandomLines(10));
            await rpc.InvokeWithParameterObjectAsync <Task>(Methods.TextDocumentDidSave.Name, TestUtils.GetSaveFileParams(filename, newContent));

            var trackedContent = await this.GetFileContentInMemoryAsync(filename);

            Assert.AreEqual(newContent, Builder.JoinLines(trackedContent));
        }
Esempio n. 6
0
        public async Task TextContentTrackingAsync()
        {
            async Task RunTest(bool emptyLastLine)
            {
                var fileSize        = 10;
                var filename        = inputGenerator.GenerateRandomFile(fileSize, emptyLastLine, false);
                var expectedContent = TestUtils.GetContent(filename);
                var openParams      = TestUtils.GetOpenFileParams(filename);

                await SetupAsync();

                await rpc.InvokeWithParameterObjectAsync <Task>(Methods.TextDocumentDidOpen.Name, openParams);

                // check that the file content is accurately reflected upon opening

                var trackedContent = await this.GetFileContentInMemoryAsync(filename);

                var expected = Builder.JoinLines(expectedContent.ToArray());
                var got      = Builder.JoinLines(trackedContent);

                Assert.IsNotNull(trackedContent);
                Assert.AreEqual(expectedContent.Count(), trackedContent.Count(), $"expected: \n{expected} \ngot: \n{got}");
                Assert.AreEqual(expected, got);

                // check whether a single array of changes is processed correctly

                var edits = inputGenerator.MakeRandomEdits(50, ref expectedContent, fileSize, false);
                await rpc.InvokeWithParameterObjectAsync <Task>(Methods.TextDocumentDidChange.Name, TestUtils.GetChangedFileParams(filename, edits));

                trackedContent = await this.GetFileContentInMemoryAsync(filename);

                Assert.AreEqual(expectedContent.Count(), trackedContent.Count());
                Assert.AreEqual(Builder.JoinLines(expectedContent.ToArray()), Builder.JoinLines(trackedContent));

                // check if changes are also processed correctly if many changes (array of length one) are given in rapid succession

                for (var testRep = 0; testRep < 20; ++testRep)
                {
                    edits = inputGenerator.MakeRandomEdits(50, ref expectedContent, fileSize, false);

                    Task[] processing = new Task[edits.Length];
                    for (var i = 0; i < edits.Length; ++i)
                    {
                        processing[i] = rpc.InvokeWithParameterObjectAsync <Task>(Methods.TextDocumentDidChange.Name, TestUtils.GetChangedFileParams(filename, new[] { edits[i] }));
                    }

                    for (var i = edits.Length - 1; i >= 0; --i)
                    {
                        await processing[i];
                    }
                    trackedContent = await this.GetFileContentInMemoryAsync(filename);

                    expected = Builder.JoinLines(expectedContent.ToArray());
                    got      = Builder.JoinLines(trackedContent);
                    Assert.AreEqual(expectedContent.Count(), trackedContent.Count(), $"expected: \n{expected} \ngot: \n{got}");
                    Assert.AreEqual(expected, got);
                }
            }

            await RunTest(emptyLastLine : true);
            await RunTest(emptyLastLine : false);
        }