public async Task Run_invokes_operation_at_least_once(int maximumRetryCount, bool canceled)
        {
            // Arrange
            TransientFaultDetectionStrategy transientFaultDetectionStrategy =
                new DelegatingTransientFaultDetectionStrategy(exception => true);

            RetryIntervalStrategy retryIntervalStrategy =
                new DelegatingRetryIntervalStrategy(
                    retried => TimeSpan.FromMilliseconds(1),
                    immediateFirstRetry: false);

            var sut = new RetryPolicy(
                maximumRetryCount,
                transientFaultDetectionStrategy,
                retryIntervalStrategy);

            var functionProvider  = Mock.Of <IFunctionProvider>();
            var cancellationToken = new CancellationToken(canceled);

            // Act
            await sut.Run(functionProvider.Func <CancellationToken, Task>, cancellationToken);

            // Assert
            Mock.Get(functionProvider).Verify(x => x.Func <CancellationToken, Task>(cancellationToken), Times.AtLeastOnce());
        }
        public void constructor_has_guard_clause_against_negative_maximumRetryCount(int maximumRetryCount)
        {
            TransientFaultDetectionStrategy transientFaultDetectionStrategy =
                new DelegatingTransientFaultDetectionStrategy(exception => true);
            RetryIntervalStrategy retryIntervalStrategy =
                new DelegatingRetryIntervalStrategy(
                    retried => TimeSpan.FromMilliseconds(1),
                    immediateFirstRetry: false);

            Action action = () => new RetryPolicy(maximumRetryCount, transientFaultDetectionStrategy, retryIntervalStrategy);

            action.Should().Throw <ArgumentOutOfRangeException>().Where(x => x.ParamName == "maximumRetryCount");
        }
        public void IsTransientException_relays_to_function(bool expected)
        {
            var fixture          = new Fixture();
            var exception        = fixture.Create <Exception>();
            var functionProvider = Mock.Of <IFunctionProvider>(
                x => x.Func(exception) == expected);
            Func <Exception, bool> func = functionProvider.Func;
            var sut = new DelegatingTransientFaultDetectionStrategy(func);

            bool actual = sut.IsTransientException(exception);

            actual.Should().Be(expected);
        }
        public void IsTransientResult_relays_to_func(bool expected)
        {
            var fixture          = new Fixture();
            var result           = fixture.Create <Result>();
            var functionProvider = Mock.Of <IFunctionProvider>(
                x => x.ResultFunc(result) == expected);
            Func <Exception, bool> exceptionFunc = functionProvider.ExceptionFunc;
            Func <Result, bool>    resultFunc    = functionProvider.ResultFunc;
            var sut = new DelegatingTransientFaultDetectionStrategy <Result>(exceptionFunc, resultFunc);

            bool actual = sut.IsTransientResult(result);

            actual.Should().Be(expected);
        }
        public void modest_constructor_sets_exceptionFunc_to_true_constant_function()
        {
            var sut = new DelegatingTransientFaultDetectionStrategy <Result>(result => false);

            sut.IsTransientException(new Fixture().Create <Exception>()).Should().BeTrue();
        }