// 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
{
///
/// Base class to write unit tests for applications and libraries built using Reactive Extensions.
///
public class ReactiveTest
{
///
/// Default virtual time used for creation of observable sequences in -based unit tests.
///
public const long Created = 100;
///
/// Default virtual time used to subscribe to observable sequences in -based unit tests.
///
public const long Subscribed = 200;
///
/// Default virtual time used to dispose subscriptions in -based unit tests.
///
public const long Disposed = 1000;
///
/// Factory method for an OnNext notification record at a given time with a given value.
///
/// The element type for the resulting notification object.
/// Recorded virtual time the OnNext notification occurs.
/// Recorded value stored in the OnNext notification.
/// Recorded OnNext notification.
public static Recorded> OnNext(long ticks, T value)
{
return new Recorded>(ticks, Notification.CreateOnNext(value));
}
///
/// 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.
///
/// The element type for the resulting notification object.
/// Recorded virtual time the OnNext notification occurs.
/// Predicate function to check the OnNext notification value against an expected value.
/// Recorded OnNext notification with a predicate to assert a given value.
/// is null.
public static Recorded> OnNext(long ticks, Func predicate)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
return new Recorded>(ticks, new OnNextPredicate(predicate));
}
///
/// Factory method for an OnCompleted notification record at a given time.
///
/// The element type for the resulting notification object.
/// Recorded virtual time the OnCompleted notification occurs.
/// Recorded OnCompleted notification.
public static Recorded> OnCompleted(long ticks)
{
return new Recorded>(ticks, Notification.CreateOnCompleted());
}
///
/// Factory method for an OnCompleted notification record at a given time, using inference to determine the type of .
///
/// The element type for the resulting notification object.
/// Recorded virtual time the OnCompleted notification occurs.
/// Object solely used to infer the type of the type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.
/// Recorded OnCompleted notification.
public static Recorded> OnCompleted(long ticks, T witness)
{
return new Recorded>(ticks, Notification.CreateOnCompleted());
}
///
/// Factory method for an OnError notification record at a given time with a given error.
///
/// The element type for the resulting notification object.
/// Recorded virtual time the OnError notification occurs.
/// Recorded exception stored in the OnError notification.
/// Recorded OnError notification.
/// is null.
public static Recorded> OnError(long ticks, Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
return new Recorded>(ticks, Notification.CreateOnError(exception));
}
///
/// 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.
///
/// The element type for the resulting notification object.
/// Recorded virtual time the OnError notification occurs.
/// Predicate function to check the OnError notification value against an expected exception.
/// Recorded OnError notification with a predicate to assert a given exception.
/// is null.
public static Recorded> OnError(long ticks, Func predicate)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
return new Recorded>(ticks, new OnErrorPredicate(predicate));
}
///
/// Factory method for an OnError notification record at a given time with a given error, using inference to determine the type of .
///
/// The element type for the resulting notification object.
/// Recorded virtual time the OnError notification occurs.
/// Recorded exception stored in the OnError notification.
/// Object solely used to infer the type of the type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.
/// Recorded OnError notification.
/// is null.
public static Recorded> OnError(long ticks, Exception exception, T witness)
{
if (exception == null)
throw new ArgumentNullException("exception");
return new Recorded>(ticks, Notification.CreateOnError(exception));
}
///
/// 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 .
///
/// The element type for the resulting notification object.
/// Recorded virtual time the OnError notification occurs.
/// Predicate function to check the OnError notification value against an expected exception.
/// Object solely used to infer the type of the type parameter. This parameter is typically used when creating a sequence of anonymously typed elements.
/// Recorded OnError notification with a predicate to assert a given exception.
/// is null.
public static Recorded> OnError(long ticks, Func predicate, T witness)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
return new Recorded>(ticks, new OnErrorPredicate(predicate));
}
///
/// Factory method for a subscription record based on a given subscription and disposal time.
///
/// Virtual time indicating when the subscription was created.
/// Virtual time indicating when the subscription was disposed.
/// Subscription object.
public static Subscription Subscribe(long start, long end)
{
return new Subscription(start, end);
}
///
/// Factory method for a subscription record based on a given subscription time.
///
/// Virtual time indicating when the subscription was created.
/// Subscription object.
public static Subscription Subscribe(long start)
{
return new Subscription(start);
}
#region Predicate-based notification assert helper classes
class OnNextPredicate : PredicateNotification
{
private readonly Func _predicate;
public OnNextPredicate(Func predicate)
{
_predicate = predicate;
}
public override bool Equals(Notification 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 : PredicateNotification
{
private readonly Func _predicate;
public OnErrorPredicate(Func predicate)
{
_predicate = predicate;
}
public override bool Equals(Notification 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 : Notification
{
#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 observer)
{
throw new NotSupportedException();
}
public override TResult Accept(IObserver observer)
{
throw new NotSupportedException();
}
public override void Accept(Action onNext, Action onError, Action onCompleted)
{
throw new NotSupportedException();
}
public override TResult Accept(Func onNext, Func onError, Func onCompleted)
{
throw new NotSupportedException();
}
#endregion
}
#endregion
}
}