1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Reactive;
namespace Microsoft.Reactive.Testing
{
/// <summary>
/// Base class to write unit tests for applications and libraries built using Reactive Extensions.
/// </summary>
public class ReactiveTest
{
/// <summary>
/// Default virtual time used for creation of observable sequences in <see cref="ReactiveTest"/>-based unit tests.
/// </summary>
public const long Created = 100;
/// <summary>
/// Default virtual time used to subscribe to observable sequences in <see cref="ReactiveTest"/>-based unit tests.
/// </summary>
public const long Subscribed = 200;
/// <summary>
/// Default virtual time used to dispose subscriptions in <see cref="ReactiveTest"/>-based unit tests.
/// </summary>
public const long Disposed = 1000;
/// <summary>
/// Factory method for an OnNext notification record at a given time with a given value.
/// </summary>
/// <typeparam name="T">The element type for the resulting notification object.</typeparam>
/// <param name="ticks">Recorded virtual time the OnNext notification occurs.</param>
/// <param name="value">Recorded value stored in the OnNext notification.</param>
/// <returns>Recorded OnNext notification.</returns>
public static Recorded<Notification<T>> OnNext<T>(long ticks, T value)
{
return new Recorded<Notification<T>>(ticks, Notification.CreateOnNext<T>(value));
}
/// <summary>
/// Factory method for writing an assert that checks for an OnNext notification record at a given time, using the specified predicate to check the value.
/// </summary>
/// <typeparam name="T">The element type for the resulting notification object.</typeparam>
/// <param name="ticks">Recorded virtual time the OnNext notification occurs.</param>
/// <param name="predicate">Predicate function to check the OnNext notification value against an expected value.</param>
/// <returns>Recorded OnNext notification with a predicate to assert a given value.</returns>
/// <exception cref="ArgumentNullException"><paramref name="predicate"/> is null.</exception>
public static Recorded<Notification<T>> OnNext<T>(long ticks, Func<T, bool> predicate)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
return new Recorded<Notification<T>>(ticks, new OnNextPredicate<T>(predicate));
}
/// <summary>
/// Factory method for an OnCompleted notification record at a given time.
/// </summary>
/// <typeparam name="T">The element type for the resulting notification object.</typeparam>
/// <param name="ticks">Recorded virtual time the OnCompleted notification occurs.</param>
/// <returns>Recorded OnCompleted notification.</returns>
public static Recorded<Notification<T>> OnCompleted<T>(long ticks)
{
return new Recorded<Notification<T>>(ticks, Notification.CreateOnCompleted<T>());
}
/// <summary>
/// Factory method for an OnCompleted notification record at a given time, using inference to determine the type of <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">The element type for the resulting notification object.</typeparam>
/// <param name="ticks">Recorded virtual time the OnCompleted notification occurs.</param>
/// <param name="witness">Object solely used to infer the type of the <typeparamref name="T"/> type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.</param>
/// <returns>Recorded OnCompleted notification.</returns>
public static Recorded<Notification<T>> OnCompleted<T>(long ticks, T witness)
{
return new Recorded<Notification<T>>(ticks, Notification.CreateOnCompleted<T>());
}
/// <summary>
/// Factory method for an OnError notification record at a given time with a given error.
/// </summary>
/// <typeparam name="T">The element type for the resulting notification object.</typeparam>
/// <param name="ticks">Recorded virtual time the OnError notification occurs.</param>
/// <param name="exception">Recorded exception stored in the OnError notification.</param>
/// <returns>Recorded OnError notification.</returns>
/// <exception cref="ArgumentNullException"><paramref name="exception"/> is null.</exception>
public static Recorded<Notification<T>> OnError<T>(long ticks, Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
return new Recorded<Notification<T>>(ticks, Notification.CreateOnError<T>(exception));
}
/// <summary>
/// Factory method for writing an assert that checks for an OnError notification record at a given time, using the specified predicate to check the exception.
/// </summary>
/// <typeparam name="T">The element type for the resulting notification object.</typeparam>
/// <param name="ticks">Recorded virtual time the OnError notification occurs.</param>
/// <param name="predicate">Predicate function to check the OnError notification value against an expected exception.</param>
/// <returns>Recorded OnError notification with a predicate to assert a given exception.</returns>
/// <exception cref="ArgumentNullException"><paramref name="predicate"/> is null.</exception>
public static Recorded<Notification<T>> OnError<T>(long ticks, Func<Exception, bool> predicate)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
return new Recorded<Notification<T>>(ticks, new OnErrorPredicate<T>(predicate));
}
/// <summary>
/// Factory method for an OnError notification record at a given time with a given error, using inference to determine the type of <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">The element type for the resulting notification object.</typeparam>
/// <param name="ticks">Recorded virtual time the OnError notification occurs.</param>
/// <param name="exception">Recorded exception stored in the OnError notification.</param>
/// <param name="witness">Object solely used to infer the type of the <typeparamref name="T"/> type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.</param>
/// <returns>Recorded OnError notification.</returns>
/// <exception cref="ArgumentNullException"><paramref name="exception"/> is null.</exception>
public static Recorded<Notification<T>> OnError<T>(long ticks, Exception exception, T witness)
{
if (exception == null)
throw new ArgumentNullException("exception");
return new Recorded<Notification<T>>(ticks, Notification.CreateOnError<T>(exception));
}
/// <summary>
/// Factory method for writing an assert that checks for an OnError notification record at a given time, using the specified predicate to check the exception and inference to determine the type of <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">The element type for the resulting notification object.</typeparam>
/// <param name="ticks">Recorded virtual time the OnError notification occurs.</param>
/// <param name="predicate">Predicate function to check the OnError notification value against an expected exception.</param>
/// <param name="witness">Object solely used to infer the type of the <typeparamref name="T"/> type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.</param>
/// <returns>Recorded OnError notification with a predicate to assert a given exception.</returns>
/// <exception cref="ArgumentNullException"><paramref name="predicate"/> is null.</exception>
public static Recorded<Notification<T>> OnError<T>(long ticks, Func<Exception, bool> predicate, T witness)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
return new Recorded<Notification<T>>(ticks, new OnErrorPredicate<T>(predicate));
}
/// <summary>
/// Factory method for a subscription record based on a given subscription and disposal time.
/// </summary>
/// <param name="start">Virtual time indicating when the subscription was created.</param>
/// <param name="end">Virtual time indicating when the subscription was disposed.</param>
/// <returns>Subscription object.</returns>
public static Subscription Subscribe(long start, long end)
{
return new Subscription(start, end);
}
/// <summary>
/// Factory method for a subscription record based on a given subscription time.
/// </summary>
/// <param name="start">Virtual time indicating when the subscription was created.</param>
/// <returns>Subscription object.</returns>
public static Subscription Subscribe(long start)
{
return new Subscription(start);
}
#region Predicate-based notification assert helper classes
class OnNextPredicate<T> : PredicateNotification<T>
{
private readonly Func<T, bool> _predicate;
public OnNextPredicate(Func<T, bool> predicate)
{
_predicate = predicate;
}
public override bool Equals(Notification<T> other)
{
if (Object.ReferenceEquals(this, other))
return true;
if (Object.ReferenceEquals(other, null))
return false;
if (other.Kind != NotificationKind.OnNext)
return false;
return _predicate(other.Value);
}
}
class OnErrorPredicate<T> : PredicateNotification<T>
{
private readonly Func<Exception, bool> _predicate;
public OnErrorPredicate(Func<Exception, bool> predicate)
{
_predicate = predicate;
}
public override bool Equals(Notification<T> other)
{
if (Object.ReferenceEquals(this, other))
return true;
if (Object.ReferenceEquals(other, null))
return false;
if (other.Kind != NotificationKind.OnError)
return false;
return _predicate(other.Exception);
}
}
abstract class PredicateNotification<T> : Notification<T>
{
#region Non-implemented members (by design)
public override T Value
{
get { throw new NotSupportedException(); }
}
public override bool HasValue
{
get { throw new NotSupportedException(); }
}
public override Exception Exception
{
get { throw new NotSupportedException(); }
}
public override NotificationKind Kind
{
get { throw new NotSupportedException(); }
}
public override void Accept(IObserver<T> observer)
{
throw new NotSupportedException();
}
public override TResult Accept<TResult>(IObserver<T, TResult> observer)
{
throw new NotSupportedException();
}
public override void Accept(Action<T> onNext, Action<Exception> onError, Action onCompleted)
{
throw new NotSupportedException();
}
public override TResult Accept<TResult>(Func<T, TResult> onNext, Func<Exception, TResult> onError, Func<TResult> onCompleted)
{
throw new NotSupportedException();
}
#endregion
}
#endregion
}
}
|