예제 #1
0
        public async Task DocumentHighlights_Success()
        {
            await Connect();

            const int line   = 5;
            const int column = 5;
            var       expectedDocumentPath = AbsoluteDocumentPath;
            var       expectedDocumentUri  = DocumentUri.FromFileSystemPath(expectedDocumentPath);

            var expectedHighlights = new DocumentHighlightContainer(
                new DocumentHighlight {
                Kind  = DocumentHighlightKind.Write,
                Range = new Range {
                    Start = new Position {
                        Line      = line,
                        Character = column
                    },
                    End = new Position {
                        Line      = line,
                        Character = column
                    }
                },
            });

            ServerDispatcher.HandleRequest <DocumentHighlightParams, DocumentHighlightContainer>(DocumentNames.DocumentHighlight, (request, cancellationToken) => {
                Assert.NotNull(request.TextDocument);

                Assert.Equal(expectedDocumentUri, request.TextDocument.Uri);

                Assert.Equal(line, request.Position.Line);
                Assert.Equal(column, request.Position.Character);

                return(Task.FromResult(expectedHighlights));
            });

            var definitions = await LanguageClient.TextDocument.DocumentHighlights(AbsoluteDocumentPath, line, column);

            var actualDefinitions = definitions.ToArray();

            Assert.Collection(actualDefinitions, actualHighlight => {
                var expectedHighlight = expectedHighlights.Single();

                Assert.Equal(DocumentHighlightKind.Write, expectedHighlight.Kind);

                Assert.NotNull(actualHighlight.Range);
                Assert.NotNull(actualHighlight.Range.Start);
                Assert.NotNull(actualHighlight.Range.End);
                Assert.Equal(expectedHighlight.Range.Start.Line, actualHighlight.Range.Start.Line);
                Assert.Equal(expectedHighlight.Range.Start.Character, actualHighlight.Range.Start.Character);
                Assert.Equal(expectedHighlight.Range.End.Line, actualHighlight.Range.End.Line);
                Assert.Equal(expectedHighlight.Range.End.Character, actualHighlight.Range.End.Character);
            });
        }
예제 #2
0
        public void KeepAliveNoConnections()
        {
            var keepAlive      = TimeSpan.FromSeconds(3);
            var pipeName       = Guid.NewGuid().ToString();
            var requestHandler = new Mock <IRequestHandler>(MockBehavior.Strict);
            var dispatcher     = new ServerDispatcher(requestHandler.Object, new EmptyDiagnosticListener());
            var startTime      = DateTime.Now;

            dispatcher.ListenAndDispatchConnections(pipeName, keepAlive);

            Assert.True((DateTime.Now - startTime) > keepAlive);
        }
예제 #3
0
        public async Task FailedConnectionShoudlCreateFailedConnectionData()
        {
            var tcs                = new TaskCompletionSource <NamedPipeServerStream>();
            var handler            = new Mock <IRequestHandler>(MockBehavior.Strict);
            var connectionDataTask = ServerDispatcher.CreateHandleConnectionTask(tcs.Task, handler.Object, CancellationToken.None);

            tcs.SetException(new Exception());
            var connectionData = await connectionDataTask.ConfigureAwait(false);

            Assert.Equal(ServerDispatcher.CompletionReason.CompilationNotStarted, connectionData.CompletionReason);
            Assert.Null(connectionData.KeepAlive);
        }
 /// <summary>
 ///     Add standard handlers for sever initialisation.
 /// </summary>
 void HandleServerInitialize()
 {
     ServerDispatcher.HandleRequest <InitializeParams, InitializeResult>("initialize", (request, cancellationToken) => {
         return(Task.FromResult(new InitializeResult {
             Capabilities = new ServerCapabilities {
                 HoverProvider = true
             }
         }));
     });
     ServerDispatcher.HandleEmptyNotification("initialized", () => {
         Log.LogInformation("Server initialized.");
     });
 }
        public async Task Hover_Success()
        {
            await Connect();

            const int line   = 5;
            const int column = 5;
            var       expectedHoverContent = new MarkedStringsOrMarkupContent("123", "456", "789");

            ServerDispatcher.HandleRequest <TextDocumentPositionParams, Hover>(DocumentNames.Hover, (request, cancellationToken) =>
            {
                Assert.NotNull(request.TextDocument);

                Assert.Equal(AbsoluteDocumentPath,
                             DocumentUri.GetFileSystemPath(request.TextDocument.Uri)
                             );

                Assert.Equal(line, request.Position.Line);
                Assert.Equal(column, request.Position.Character);

                return(Task.FromResult(new Hover
                {
                    Contents = expectedHoverContent,
                    Range = new Range
                    {
                        Start = request.Position,
                        End = request.Position
                    }
                }));
            });

            var hover = await LanguageClient.TextDocument.Hover(AbsoluteDocumentPath, line, column);

            Assert.NotNull(hover.Range);
            Assert.NotNull(hover.Range.Start);
            Assert.NotNull(hover.Range.End);

            Assert.Equal(line, hover.Range.Start.Line);
            Assert.Equal(column, hover.Range.Start.Character);

            Assert.Equal(line, hover.Range.End.Line);
            Assert.Equal(column, hover.Range.End.Character);

            Assert.NotNull(hover.Contents);
            Assert.True(expectedHoverContent.HasMarkedStrings);
            Assert.Equal(expectedHoverContent.MarkedStrings
                         .Select(markedString => markedString.Value),
                         hover.Contents.MarkedStrings.Select(
                             markedString => markedString.Value
                             )
                         );
        }
예제 #6
0
        public async Task ClientConnectionThrowsHandlingBuild()
        {
            var ex = new Exception();
            var clientConnection = new Mock <IClientConnection>();

            clientConnection
            .Setup(x => x.HandleConnection(It.IsAny <bool>(), It.IsAny <CancellationToken>()))
            .Returns(FromException <ConnectionData>(ex));

            var task = Task.FromResult(clientConnection.Object);

            var connectionData = await ServerDispatcher.HandleClientConnection(task).ConfigureAwait(true);

            Assert.Equal(CompletionReason.ClientException, connectionData.CompletionReason);
            Assert.Null(connectionData.KeepAlive);
        }
예제 #7
0
        public void KeepAliveAfterSingleConnection()
        {
            var connection = CreateClientConnection(CompletionReason.CompilationCompleted);
            var host       = CreateClientConnectionHost(
                Task.FromResult(connection),
                new TaskCompletionSource <IClientConnection>().Task);
            var listener   = new TestableDiagnosticListener();
            var keepAlive  = TimeSpan.FromSeconds(1);
            var dispatcher = new ServerDispatcher(host, listener);

            dispatcher.ListenAndDispatchConnections(keepAlive);

            Assert.Equal(1, listener.CompletedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True(listener.HitKeepAliveTimeout);
        }
        public async Task DocumentSymbols_DocumentSymbol_Success()
        {
            await Connect();

            const int line                 = 5;
            const int character            = 6;
            var       expectedDocumentPath = AbsoluteDocumentPath;
            var       expectedDocumentUri  = DocumentUri.FromFileSystemPath(expectedDocumentPath);
            var       detail               = "some detail";

            var documentSymbol = new DocumentSymbol {
                Detail = detail,
                Kind   = SymbolKind.Class,
                Range  = new Range(new Position(line, character), new Position(line, character))
            };
            var expectedSymbols = new SymbolInformationOrDocumentSymbolContainer(
                new SymbolInformationOrDocumentSymbol(documentSymbol));

            ServerDispatcher.HandleRequest <DocumentSymbolParams, SymbolInformationOrDocumentSymbolContainer>(DocumentNames.DocumentSymbol, (request, cancellationToken) => {
                Assert.NotNull(request.TextDocument);

                Assert.Equal(expectedDocumentUri, request.TextDocument.Uri);

                return(Task.FromResult(expectedSymbols));
            });
            var documentSymbolParams = new DocumentSymbolParams {
                TextDocument = new TextDocumentIdentifier(expectedDocumentUri)
            };
            var symbols = await LanguageClient.SendRequest <SymbolInformationOrDocumentSymbolContainer>(DocumentNames.DocumentSymbol, documentSymbolParams);

            var actualSymbols = symbols.ToArray();

            Assert.Collection(actualSymbols, actualSymbol => {
                var expectedSymbol = expectedSymbols.Single();

                Assert.True(expectedSymbol.IsDocumentSymbol);

                Assert.NotNull(actualSymbol.DocumentSymbol);
                Assert.Equal(expectedSymbol.DocumentSymbol.Detail, actualSymbol.DocumentSymbol.Detail);
                Assert.Equal(expectedSymbol.DocumentSymbol.Kind, actualSymbol.DocumentSymbol.Kind);
                Assert.Equal(expectedSymbol.DocumentSymbol.Range.Start.Line, actualSymbol.DocumentSymbol.Range.Start.Line);
                Assert.Equal(expectedSymbol.DocumentSymbol.Range.Start.Character, actualSymbol.DocumentSymbol.Range.Start.Character);
                Assert.Equal(expectedSymbol.DocumentSymbol.Range.End.Line, actualSymbol.DocumentSymbol.Range.End.Line);
                Assert.Equal(expectedSymbol.DocumentSymbol.Range.End.Character, actualSymbol.DocumentSymbol.Range.End.Character);
            });
        }
예제 #9
0
        public void KeepAliveNoConnections()
        {
            var keepAlive      = TimeSpan.FromSeconds(3);
            var connectionHost = new Mock <IClientConnectionHost>();

            connectionHost
            .Setup(x => x.CreateListenTask(It.IsAny <CancellationToken>()))
            .Returns(new TaskCompletionSource <IClientConnection>().Task);

            var listener   = new TestableDiagnosticListener();
            var dispatcher = new ServerDispatcher(connectionHost.Object, listener);
            var startTime  = DateTime.Now;

            dispatcher.ListenAndDispatchConnections(keepAlive);

            Assert.True(listener.HitKeepAliveTimeout);
        }
예제 #10
0
        public async Task KeepAliveAfterSimultaneousConnection()
        {
            var totalCount  = 2;
            var readySource = new TaskCompletionSource <bool>();
            var list        = new List <TaskCompletionSource <ConnectionData> >();
            var host        = new Mock <IClientConnectionHost>();

            host
            .Setup(x => x.CreateListenTask(It.IsAny <CancellationToken>()))
            .Returns((CancellationToken ct) =>
            {
                if (list.Count < totalCount)
                {
                    var source = new TaskCompletionSource <ConnectionData>();
                    var client = CreateClientConnection(source.Task);
                    list.Add(source);
                    return(Task.FromResult(client));
                }

                readySource.SetResult(true);
                return(new TaskCompletionSource <IClientConnection>().Task);
            });

            var keepAlive      = TimeSpan.FromSeconds(1);
            var listener       = new TestableDiagnosticListener();
            var dispatcherTask = Task.Run(() =>
            {
                var dispatcher = new ServerDispatcher(host.Object, listener);
                dispatcher.ListenAndDispatchConnections(keepAlive);
            });


            await readySource.Task.ConfigureAwait(true);

            foreach (var source in list)
            {
                source.SetResult(new ConnectionData(CompletionReason.Completed));
            }

            await dispatcherTask.ConfigureAwait(true);

            Assert.Equal(totalCount, listener.ProcessedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True(listener.HitKeepAliveTimeout);
        }
예제 #11
0
        public async Task KeepAliveAfterSingleConnection()
        {
            var keepAlive      = TimeSpan.FromSeconds(1);
            var listener       = new TestableDiagnosticListener();
            var pipeName       = Guid.NewGuid().ToString();
            var dispatcherTask = Task.Run(() =>
            {
                var dispatcher = new ServerDispatcher(CreateNopRequestHandler().Object, listener);
                dispatcher.ListenAndDispatchConnections(pipeName, keepAlive);
            });

            await RunCSharpCompile(pipeName, HelloWorldSourceText).ConfigureAwait(false);

            await dispatcherTask.ConfigureAwait(false);

            Assert.Equal(1, listener.ProcessedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True((DateTime.Now - listener.LastProcessedTime.Value) > keepAlive);
        }
예제 #12
0
파일: LobbyScreen.cs 프로젝트: Mattias1/td
        private void startGame()
        {
            // these are different for clients
            var commandDispatcher = new ServerCommandDispatcher(new DefaultCommandExecutor());
            var requestDispatcher = new ServerRequestDispatcher(commandDispatcher);
            var dispatcher        = new ServerDispatcher(commandDispatcher);

            var meta = new GameMeta(logger, dispatcher);

            var gameState    = GameStateBuilder.Generate(meta, new DefaultTilemapGenerator(logger));
            var gameInstance = new GameInstance(
                gameState,
                new GameCamera(inputManager, meta, gameState.Level.Tilemap.Radius),
                requestDispatcher
                );

            Parent.AddScreenLayerOnTopOf(this, new GameUI(Parent, Geometries, gameInstance, inputManager));
            gameStarted = true;
            Destroy();
        }
예제 #13
0
        public void TestSendingMessageFromClientToServer()
        {
            IServerBusiness  business = new ServerBusiness("groupsSaveFile", "clientsSaveFile");
            ServerDispatcher server   = new ServerDispatcher(business, "127.0.0.1", 10000);

            ClientServerAccess clientLinkToServer = new ClientServerAccess("127.0.0.1", 10000);

            try
            {
                clientLinkToServer.CreateUser("Henry", "hunter2");
            }
            catch (Exception)
            {
                Assert.IsTrue(true);
            }
            Assert.IsTrue(clientLinkToServer.Connect("Henry", "hunter2"));

            server.CloseConnection();

            Thread.Sleep(1000);
        }
예제 #14
0
        public async Task KeepAliveAfterMultipleConnection()
        {
            var keepAlive      = TimeSpan.FromSeconds(1);
            var listener       = new TestableDiagnosticListener();
            var pipeName       = Guid.NewGuid().ToString();
            var dispatcherTask = Task.Run(() =>
            {
                var dispatcher = new ServerDispatcher(new CompilerRequestHandler(Temp.CreateDirectory().Path), listener);
                dispatcher.ListenAndDispatchConnections(pipeName, keepAlive);
            });

            for (int i = 0; i < 5; i++)
            {
                await RunCSharpCompile(pipeName, HelloWorldSourceText).ConfigureAwait(false);
            }

            await dispatcherTask.ConfigureAwait(false);

            Assert.Equal(5, listener.ProcessedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True((DateTime.Now - listener.LastProcessedTime.Value) > keepAlive);
        }
예제 #15
0
        public void KeepAliveAfterMultipleConnection()
        {
            var count = 5;
            var list  = new List <Task <IClientConnection> >();

            for (var i = 0; i < count; i++)
            {
                var connection = CreateClientConnection(CompletionReason.CompilationCompleted);
                list.Add(Task.FromResult(connection));
            }

            list.Add(new TaskCompletionSource <IClientConnection>().Task);
            var host       = CreateClientConnectionHost(list.ToArray());
            var listener   = new TestableDiagnosticListener();
            var keepAlive  = TimeSpan.FromSeconds(1);
            var dispatcher = new ServerDispatcher(host, listener);

            dispatcher.ListenAndDispatchConnections(keepAlive);

            Assert.Equal(count, listener.CompletedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True(listener.HitKeepAliveTimeout);
        }
        public async Task FoldingRanges_Success()
        {
            await Connect();

            var expectedDocumentPath = AbsoluteDocumentPath;
            var expectedDocumentUri  = DocumentUri.FromFileSystemPath(expectedDocumentPath);

            var expectedFoldingRanges = new Container <FoldingRange>(
                new FoldingRange {
                Kind           = FoldingRangeKind.Region,
                StartLine      = 5,
                StartCharacter = 1,
                EndLine        = 7,
                EndCharacter   = 2,
            });

            ServerDispatcher.HandleRequest <FoldingRangeRequestParam, Container <FoldingRange> >(DocumentNames.FoldingRange, (request, cancellationToken) => {
                Assert.NotNull(request.TextDocument);
                Assert.Equal(expectedDocumentUri, request.TextDocument.Uri);
                return(Task.FromResult(expectedFoldingRanges));
            });

            var foldingRanges = await LanguageClient.TextDocument.FoldingRanges(AbsoluteDocumentPath);

            var actualFoldingRanges = foldingRanges.ToArray();

            Assert.Collection(actualFoldingRanges, actualFoldingRange => {
                var expectedFoldingRange = expectedFoldingRanges.Single();

                Assert.Equal(FoldingRangeKind.Region, expectedFoldingRange.Kind);

                Assert.Equal(expectedFoldingRange.StartLine, actualFoldingRange.StartLine);
                Assert.Equal(expectedFoldingRange.StartCharacter, actualFoldingRange.StartCharacter);
                Assert.Equal(expectedFoldingRange.EndLine, actualFoldingRange.EndLine);
                Assert.Equal(expectedFoldingRange.EndCharacter, actualFoldingRange.EndCharacter);
            });
        }
예제 #17
0
        public void ClientExceptionShouldBeginShutdown()
        {
            var client = new Mock <IClientConnection>();

            client
            .Setup(x => x.HandleConnection(It.IsAny <bool>(), It.IsAny <CancellationToken>()))
            .Throws(new Exception());

            var listenCancellationToken = default(CancellationToken);
            var first = true;

            var host = new Mock <IClientConnectionHost>();

            host
            .Setup(x => x.CreateListenTask(It.IsAny <CancellationToken>()))
            .Returns((CancellationToken cancellationToken) =>
            {
                if (first)
                {
                    first = false;
                    return(Task.FromResult(client.Object));
                }
                else
                {
                    listenCancellationToken = cancellationToken;
                    return(Task.Delay(-1, cancellationToken).ContinueWith <IClientConnection>(_ => null, TaskScheduler.Default));
                }
            });

            var listener   = new TestableDiagnosticListener();
            var dispatcher = new ServerDispatcher(host.Object, listener);

            dispatcher.ListenAndDispatchConnections(TimeSpan.FromSeconds(10));

            Assert.True(listener.HasDetectedBadConnection);
            Assert.True(listenCancellationToken.IsCancellationRequested);
        }
예제 #18
0
        /**
         * <summary>
         * Adds all the UI regarding this player (including a kick button for the host)
         * </summary>
         */
        public void Set(string playerID, string playerName, bool isLocalPlayer, int number, NetworkedScene networkedScene)
        {
            serverDispatcher    = networkedScene.serverDispatcher;
            playerIdentifier    = playerID;
            this.playerName     = playerName;
            this.networkService = networkedScene.networkService;
            pName = new TextBlock {
                Text = playerName, Margin = new Thickness(0, firstGUILine + (distanceBetweenPlayers * number), 0, 0)
            };
            networkedScene.EntityManager.Add(pName);


            nextColor = new Button {
                IsBorder = isLocalPlayer, Text = "Change", Width = 100, Margin = new Thickness(300, firstGUILine + (distanceBetweenPlayers * number), 10, 10)
            };
            networkedScene.EntityManager.Add(nextColor);

            toggleReady = new CustomButton()
            {
                IsBorder = isLocalPlayer, Text = "Not ready", Margin = new Thickness(450, firstGUILine + (distanceBetweenPlayers * number), 10, 10)
            };
            networkedScene.EntityManager.Add(toggleReady);

            if (isLocalPlayer)
            {
                toggleReady.Click += ChangeReady;
                previousTeam       = new Button {
                    Text = "<", Width = 30, Height = 30, Margin = new Thickness(110, firstGUILine + (distanceBetweenPlayers * number), 0, 0)
                };
                nextTeam = new Button {
                    Text = ">", Width = 30, Height = 30, Margin = new Thickness(230, firstGUILine + (distanceBetweenPlayers * number), 0, 0)
                };

                previousTeam.Click += PreviousTeam;
                nextTeam.Click     += NextTeam;

                networkedScene.EntityManager.Add(previousTeam);
                networkedScene.EntityManager.Add(nextTeam);

                nextColor.Click += NextColor;
            }
            textTeam = new TextBlock {
                Text = "No team", Margin = new Thickness(150, firstGUILine + (distanceBetweenPlayers * number), 10, 10)
            };
            networkedScene.EntityManager.Add(textTeam);


            if (networkedScene.isHost)
            {
                playerColor           = networkedScene.serverDispatcher.FindNextColor(-1);
                nextColor.Text        = ClientDispatcher.colorNames[playerColor];
                nextColor.Foreground  = ClientDispatcher.colors[playerColor];
                nextColor.BorderColor = ClientDispatcher.colors[playerColor];

                kickButton = new Button {
                    IsVisible = !isLocalPlayer, Text = "Kick", Margin = new Thickness(600, firstGUILine + (distanceBetweenPlayers * number), 10, 10)
                };
                kickButton.Click += Kick;
                networkedScene.EntityManager.Add(kickButton);
            }
            WaveServices.Layout.PerformLayout();
        }
예제 #19
0
        public async Task SignatureHelp_Success()
        {
            await Connect();

            const int line   = 5;
            const int column = 5;
            var       expectedDocumentPath = AbsoluteDocumentPath;
            var       expectedDocumentUri  = DocumentUri.FromFileSystemPath(expectedDocumentPath);

            var expectedSignatureHelp = new SignatureHelp {
                ActiveParameter = 0,
                ActiveSignature = 0,
                Signatures      = new[] {
                    new SignatureInformation {
                        Documentation = new StringOrMarkupContent("test documentation"),
                        Label         = "TestSignature",
                        Parameters    = new[] {
                            new ParameterInformation {
                                Documentation = "test parameter documentation",
                                Label         = "parameter label"
                            }
                        }
                    }
                }
            };

            ServerDispatcher.HandleRequest <TextDocumentPositionParams, SignatureHelp>(DocumentNames.SignatureHelp, (request, cancellationToken) => {
                Assert.NotNull(request.TextDocument);

                Assert.Equal(expectedDocumentUri, request.TextDocument.Uri);

                Assert.Equal(line, request.Position.Line);
                Assert.Equal(column, request.Position.Character);

                return(Task.FromResult(expectedSignatureHelp));
            });

            var actualSignatureHelp = await LanguageClient.TextDocument.SignatureHelp(AbsoluteDocumentPath, line, column);

            Assert.Equal(expectedSignatureHelp.ActiveParameter, actualSignatureHelp.ActiveParameter);
            Assert.Equal(expectedSignatureHelp.ActiveSignature, actualSignatureHelp.ActiveSignature);

            var actualSignatures = actualSignatureHelp.Signatures.ToArray();

            Assert.Collection(actualSignatures, actualSignature => {
                var expectedSignature = expectedSignatureHelp.Signatures.ToArray()[0];

                Assert.True(actualSignature.Documentation.HasString);
                Assert.Equal(expectedSignature.Documentation.String, actualSignature.Documentation.String);

                Assert.Equal(expectedSignature.Label, actualSignature.Label);

                var expectedParameters = expectedSignature.Parameters.ToArray();
                var actualParameters   = actualSignature.Parameters.ToArray();

                Assert.Collection(actualParameters, actualParameter => {
                    var expectedParameter = expectedParameters[0];
                    Assert.True(actualParameter.Documentation.HasString);
                    Assert.Equal(expectedParameter.Documentation.String, actualParameter.Documentation.String);
                    Assert.Equal(expectedParameter.Label, actualParameter.Label);
                });
            });
        }
        public async Task Completions_Success()
        {
            await Connect();

            const int line   = 5;
            const int column = 5;
            var       expectedDocumentPath = AbsoluteDocumentPath;
            var       expectedDocumentUri  = DocumentUri.FromFileSystemPath(expectedDocumentPath);

            var expectedCompletionItems = new CompletionItem[]
            {
                new CompletionItem
                {
                    Kind     = CompletionItemKind.Class,
                    Label    = "Class1",
                    TextEdit = new TextEdit
                    {
                        Range = new Range
                        {
                            Start = new Position
                            {
                                Line      = line,
                                Character = column
                            },
                            End = new Position
                            {
                                Line      = line,
                                Character = column
                            }
                        },
                        NewText = "Class1",
                    }
                }
            };

            ServerDispatcher.HandleRequest <TextDocumentPositionParams, CompletionList>(DocumentNames.Completion, (request, cancellationToken) =>
            {
                Assert.NotNull(request.TextDocument);

                Assert.Equal(expectedDocumentUri, request.TextDocument.Uri);

                Assert.Equal(line, request.Position.Line);
                Assert.Equal(column, request.Position.Character);

                return(Task.FromResult(new CompletionList(
                                           expectedCompletionItems,
                                           isIncomplete: true
                                           )));
            });

            var actualCompletions = await LanguageClient.TextDocument.Completions(AbsoluteDocumentPath, line, column);

            Assert.True(actualCompletions.IsIncomplete, "completions.IsIncomplete");
            Assert.NotNull(actualCompletions.Items);

            var actualCompletionItems = actualCompletions.Items.ToArray();

            Assert.Collection(actualCompletionItems, actualCompletionItem =>
            {
                var expectedCompletionItem = expectedCompletionItems[0];

                Assert.Equal(expectedCompletionItem.Kind, actualCompletionItem.Kind);
                Assert.Equal(expectedCompletionItem.Label, actualCompletionItem.Label);

                Assert.NotNull(actualCompletionItem.TextEdit);
                Assert.Equal(expectedCompletionItem.TextEdit.NewText, actualCompletionItem.TextEdit.NewText);

                Assert.NotNull(actualCompletionItem.TextEdit.Range);
                Assert.NotNull(actualCompletionItem.TextEdit.Range.Start);
                Assert.NotNull(actualCompletionItem.TextEdit.Range.End);
                Assert.Equal(expectedCompletionItem.TextEdit.Range.Start.Line, actualCompletionItem.TextEdit.Range.Start.Line);
                Assert.Equal(expectedCompletionItem.TextEdit.Range.Start.Character, actualCompletionItem.TextEdit.Range.Start.Character);
                Assert.Equal(expectedCompletionItem.TextEdit.Range.End.Line, actualCompletionItem.TextEdit.Range.End.Line);
                Assert.Equal(expectedCompletionItem.TextEdit.Range.End.Character, actualCompletionItem.TextEdit.Range.End.Character);
            });
        }