예제 #1
0
        /// <summary>
        /// Asserts that the current <see cref="Delegate"/> stops throwing any exception
        /// after a specified amount of time.
        /// </summary>
        /// <remarks>
        /// The delegate is invoked. If it raises an exception,
        /// the invocation is repeated until it either stops raising any exceptions
        /// or the specified wait time is exceeded.
        /// </remarks>
        /// <param name="waitTime">
        /// The time after which the delegate should have stopped throwing any exception.
        /// </param>
        /// <param name="pollInterval">
        /// The time between subsequent invocations of the delegate.
        /// </param>
        /// <param name="because">
        /// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
        /// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
        /// </param>
        /// <param name="becauseArgs">
        /// Zero or more objects to format using the placeholders in <see cref="because" />.
        /// </param>
        /// <exception cref="ArgumentOutOfRangeException">Throws if waitTime or pollInterval are negative.</exception>
        public void NotThrowAfter(TimeSpan waitTime, TimeSpan pollInterval, string because = "", params object[] becauseArgs)
        {
            FailIfSubjectIsAsyncVoid();

            if (waitTime < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(waitTime), $"The value of {nameof(waitTime)} must be non-negative.");
            }

            if (pollInterval < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(pollInterval), $"The value of {nameof(pollInterval)} must be non-negative.");
            }

            TimeSpan? invocationEndTime = null;
            Exception exception         = null;
            var       timer             = clock.StartTimer();

            while (invocationEndTime is null || invocationEndTime < waitTime)
            {
                exception = InvokeSubjectWithInterception();
                if (exception is null)
                {
                    return;
                }

                clock.Delay(pollInterval);
                invocationEndTime = timer.Elapsed;
            }

            Execute.Assertion
            .BecauseOf(because, becauseArgs)
            .FailWith("Did not expect any exceptions after {0}{reason}, but found {1}.", waitTime, exception);
        }
예제 #2
0
        public static async Task ScheduleAsync(
            this IClock clock, TimeSpan span, Func <Task> f,
            CancellationToken cancellationToken)
        {
            await clock.Delay(span, cancellationToken).ConfigureAwait(false);

            await f().ConfigureAwait(false);
        }
예제 #3
0
        public static async Task <TResult> ScheduleAsync <TResult>(
            this IClock clock, TimeSpan span, Func <Task <TResult> > f,
            CancellationToken cancellationToken)
        {
            await clock.Delay(span, cancellationToken).ConfigureAwait(false);

            return(await f().ConfigureAwait(false));
        }
예제 #4
0
        public static async Task DelayTo(this IClock clock, DateTime delayTo, CancellationToken cancellationToken)
        {
            var span = clock.TimeTo(delayTo);

            if (span > TimeSpan.Zero)
            {
                await clock.Delay(span, cancellationToken).ConfigureAwait(false);
            }
        }
예제 #5
0
        private async Task <T> WithTimeout <T>(Task <T> mainTask, int timeout, CancellationTokenSource source)
        {
            Task timeoutTask = clock.Delay(timeout, source.Token);
            Task result      = await Task.WhenAny(mainTask, timeoutTask);

            if (result.Equals(mainTask))
            {
                return(mainTask.Result);
            }
            throw new TimeoutException();
        }
예제 #6
0
        public static async Task <Server> GetLastServer(string path, IClock clock, CancellationTokenSource source)
        {
            try
            {
                return(await GetLastServerInternal(path));
            }
            catch (IOException)
            {
                await clock.Delay(1000, source.Token);

                return(await GetLastServerInternal(path));
            }
        }
        /// <summary>
        /// Asserts that the current <see cref="Func{T}"/> stops throwing any exception
        /// after a specified amount of time.
        /// </summary>
        /// <remarks>
        /// The <see cref="Func{T}"/> is invoked. If it raises an exception,
        /// the invocation is repeated until it either stops raising any exceptions
        /// or the specified wait time is exceeded.
        /// </remarks>
        /// <param name="waitTime">
        /// The time after which the <see cref="Func{T}"/> should have stopped throwing any exception.
        /// </param>
        /// <param name="pollInterval">
        /// The time between subsequent invocations of the <see cref="Func{T}"/>.
        /// </param>
        /// <param name="because">
        /// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
        /// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
        /// </param>
        /// <param name="becauseArgs">
        /// Zero or more objects to format using the placeholders in <see cref="because" />.
        /// </param>
        /// <exception cref="ArgumentOutOfRangeException">Throws if waitTime or pollInterval are negative.</exception>
        public new AndWhichConstraint <FunctionAssertions <T>, T> NotThrowAfter(TimeSpan waitTime, TimeSpan pollInterval, string because = "", params object[] becauseArgs)
        {
            if (waitTime < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(waitTime), $"The value of {nameof(waitTime)} must be non-negative.");
            }

            if (pollInterval < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(pollInterval), $"The value of {nameof(pollInterval)} must be non-negative.");
            }

            Execute.Assertion
            .ForCondition(!ReferenceEquals(Subject, null))
            .BecauseOf(because, becauseArgs)
            .FailWith("Expected {context} not to throw any exceptions after {0}{reason}, but found <null>.", waitTime);

            TimeSpan? invocationEndTime = null;
            Exception exception         = null;
            ITimer    timer             = clock.StartTimer();

            while (invocationEndTime is null || invocationEndTime < waitTime)
            {
                try
                {
                    T result = Subject();
                    return(new AndWhichConstraint <FunctionAssertions <T>, T>(this, result));
                }
                catch (Exception e)
                {
                    exception = e;
                }

                clock.Delay(pollInterval);
                invocationEndTime = timer.Elapsed;
            }

            Execute.Assertion
            .BecauseOf(because, becauseArgs)
            .FailWith("Did not expect any exceptions after {0}{reason}, but found {1}.", waitTime, exception);

            return(new AndWhichConstraint <FunctionAssertions <T>, T>(this, default(T)));
        }