public async Task ConsumeInputRequestException()
        {
            // Setup:
            // ... Create a message reader that will return a request
            var mr = new Mock <MessageReader>(Stream.Null, null);

            mr.SetupSequence(o => o.ReadMessage())
            .ReturnsAsync(CommonObjects.RequestMessage)
            .Returns(Task.FromException <Message>(new EndOfStreamException()));

            // ... Create a JSON RPC host and register the request handler to throw exception
            var jh          = new JsonRpcHost(GetChannelBase(mr.Object, null).Object);
            var mockHandler = new Mock <Action <CommonObjects.TestMessageContents, RequestContext <CommonObjects.TestMessageContents> > >();

            mockHandler.Setup(m => m(It.IsAny <CommonObjects.TestMessageContents>(),
                                     It.IsAny <RequestContext <CommonObjects.TestMessageContents> >()))
            .Throws(new Exception());
            jh.SetRequestHandler(CommonObjects.RequestType, mockHandler.Object);

            // If: I start the input consumption loop
            await jh.ConsumeInput().WithTimeout(TimeSpan.FromSeconds(1));

            // Then:
            // ... Read message should have been called twice
            mr.Verify(o => o.ReadMessage(), Times.Exactly(2));

            // ... There should not be any outgoing messages
            var outgoing = jh.outputQueue.ToArray();

            Assert.Empty(outgoing);
        }
        public async Task ConsumeInputRequestMethodNotFound()
        {
            // Setup: Create a message reader that will return a request with method that doesn't exist
            var mr = new Mock <MessageReader>(Stream.Null, null);

            mr.SetupSequence(o => o.ReadMessage())
            .ReturnsAsync(CommonObjects.RequestMessage)
            .Returns(Task.FromException <Message>(new EndOfStreamException()));

            // If: I start the input consumption loop
            var jh = new JsonRpcHost(GetChannelBase(mr.Object, null).Object);
            await jh.ConsumeInput().WithTimeout(TimeSpan.FromSeconds(1));

            // Then:
            // ... Read message should have been called twice
            mr.Verify(o => o.ReadMessage(), Times.Exactly(2));

            // ... There should be an outgoing message with the error
            var outgoing = jh.outputQueue.ToArray();

            Assert.Single(outgoing);
            Assert.Equal(MessageType.ResponseError, outgoing[0].MessageType);
            Assert.Equal(CommonObjects.MessageId, outgoing[0].Id);
            Assert.Equal(-32601, outgoing[0].Contents.Value <int>("code"));
        }
        public async Task ConsumeInputEndOfStream()
        {
            // Setup: Create a message reader that will throw an end of stream exception on read
            var mr = new Mock <MessageReader>(Stream.Null, null);

            mr.Setup(o => o.ReadMessage()).Returns(Task.FromException <Message>(new EndOfStreamException()));

            // If: I start the input consumption thread
            // Then:
            // ... It should stop gracefully
            var jh = new JsonRpcHost(GetChannelBase(mr.Object, null).Object);
            await jh.ConsumeInput().WithTimeout(TimeSpan.FromSeconds(1));

            // ... The read message should have only been called once
            mr.Verify(o => o.ReadMessage(), Times.Once);
        }
        public async Task ConsumeInputException()
        {
            // Setup:
            // ... Create a message reader that will throw an exception on first read
            // ... throw an end of stream on second read
            var mr = new Mock <MessageReader>(Stream.Null, null);

            mr.SetupSequence(o => o.ReadMessage())
            .Returns(Task.FromException <Message>(new Exception()))
            .Returns(Task.FromException <Message>(new EndOfStreamException()));

            // If: I start the input consumption loop
            var jh = new JsonRpcHost(GetChannelBase(mr.Object, null).Object);
            await jh.ConsumeInput().WithTimeout(TimeSpan.FromSeconds(1));

            // Then:
            // ... Read message should have been called twice
            mr.Verify(o => o.ReadMessage(), Times.Exactly(2));
        }
        public async Task ConsumeInput()
        {
            // Setup:
            // ... Create a message reader that will return a message every time
            var mr          = new Mock <MessageReader>(Stream.Null, null);
            var waitForRead = new TaskCompletionSource <bool>();

            mr.Setup(o => o.ReadMessage())
            .Callback(() => waitForRead.TrySetResult(true))
            .ReturnsAsync(CommonObjects.EventMessage);

            // ... Create a no-op event handler to handle the message from the message reader
            var noOpHandler = new Mock <Func <Message, Task> >();

            noOpHandler.Setup(f => f(It.IsAny <Message>())).Returns(Task.FromResult(true));

            // ... Wire up the event handler to a new JSON RPC host
            var jh = new JsonRpcHost(GetChannelBase(mr.Object, null).Object);

            jh.eventHandlers[CommonObjects.EventType.MethodName] = noOpHandler.Object;

            // If:
            // ... I start the input consumption thread
            Task consumeInputTask = jh.ConsumeInput();

            // ... Wait for the handler to be called once, indicating the message was processed
            await waitForRead.Task.WithTimeout(TimeSpan.FromSeconds(1));

            // ... Stop the input consumption thread (the hard way) and wait for completion
            jh.cancellationTokenSource.Cancel();
            await consumeInputTask.WithTimeout(TimeSpan.FromSeconds(1));

            // Then: The event handler and read message should have been called at least once
            noOpHandler.Verify(f => f(It.IsAny <Message>()), Times.AtLeastOnce);
            mr.Verify(o => o.ReadMessage(), Times.AtLeastOnce);
        }