public OperationPromise<TResponse> RegisterOperation<TResponse>(IOperation<TResponse> operation) where TResponse : IOperationResponse
        {
            var promise = new OperationPromise<TResponse>(unchecked (_nextAvailableId++), operation);
            _activeOperations.Add(promise.Id, promise);

            return promise;
        }
        public void ShouldThrowWhenCompletingPromiseAfterCompletion()
        {
            var promise = new OperationPromise <TestResponse>(0, new TestOperation());

            promise.Complete(new TestResponse());

            Action action = () => promise.Complete(new TestResponse());

            action.ShouldThrow <InvalidOperationException>();
        }
        public void ShouldThrowWhenRegisteringCallbackAfterCompletion()
        {
            var promise = new OperationPromise <TestResponse>(0, new TestOperation());

            promise.Complete(new TestResponse());

            Action action = () => promise.Then(t => t.Method());

            action.ShouldThrow <InvalidOperationException>();
        }
        public void ShouldRegisterCallback()
        {
            var promise = new OperationPromise <TestResponse>(0, new TestOperation());

            Action <TestResponse> callback = response => response.Method();

            promise.Then(callback);

            promise.Callbacks.ShouldContain(callback);
            promise.IsCompleted.ShouldBeFalse();
        }
        public void ShouldReadPromiseId()
        {
            var writer = new NetworkOperationWriter(_map, _serializer, _transport);

            var promise = new OperationPromise <TestResponse>(0, new TestOperationWithResponse());

            writer.WriteOperationWithResponse(promise);

            var reader    = new NetworkOperationReader(_map, _serializer);
            var promiseId = reader.ReadPromiseId(_transport.SentOperations.Single().Item2);

            promiseId.ShouldBe(promise.Id);
        }
        public void ShouldInvokeCallbacksOnComplete()
        {
            var promise = new OperationPromise <TestResponse>(0, new TestOperation());

            promise.Then(t => t.Method());

            var response = new TestResponse();

            promise.Complete(response);

            promise.Response.ShouldBe(response);
            promise.IsCompleted.ShouldBeTrue();

            response.MethodInvokeCount.ShouldBe(1);
        }
        public void ShouldWriteOperationWithResponse()
        {
            var writer = new NetworkOperationWriter(_map, new SerializationService(new BinarySerializer()), _transport);

            var promise = new OperationPromise <TestResponse>(0, new TestOperationWithResponse());

            writer.WriteOperationWithResponse(promise);

            var sentOperation = _transport.SentOperations.SingleOrDefault();

            sentOperation.ShouldNotBeNull();

            sentOperation.Item1.ShouldBe(OperationCode.HandleOperationWithResponse);

            sentOperation.Item2.ShouldContainKeyAndValue((byte)OperationParameterCode.OperationId, _map.GetMappedOperation(typeof(TestOperationWithResponse)).Id);
            sentOperation.Item2.ShouldContainKeyAndValue((byte)OperationParameterCode.OperationPromiseId, promise.Id);

            sentOperation.Item2.ShouldContainKey((byte)OperationParameterCode.OperationData);
        }