Removed unneeded TestCommon code.
This commit is contained in:
parent
af14969b54
commit
ce7f79ce50
|
|
@ -1,49 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public class DictionaryEqualityComparer : IEqualityComparer<IDictionary<string, object>>
|
|
||||||
{
|
|
||||||
public bool Equals(IDictionary<string, object> x, IDictionary<string, object> y)
|
|
||||||
{
|
|
||||||
if (x.Count != y.Count)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string key in x.Keys)
|
|
||||||
{
|
|
||||||
object xVal = x[key];
|
|
||||||
object yVal;
|
|
||||||
if (!y.TryGetValue(key, out yVal))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xVal == null)
|
|
||||||
{
|
|
||||||
if (yVal == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!xVal.Equals(yVal))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetHashCode(IDictionary<string, object> obj)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public abstract class EnumHelperTestBase<TEnum> where TEnum : IComparable, IFormattable, IConvertible
|
|
||||||
{
|
|
||||||
private Func<TEnum, bool> _isDefined;
|
|
||||||
private Action<TEnum, string> _validate;
|
|
||||||
private TEnum _undefined;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper to verify that we validate enums correctly when passed as arguments etc.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="isDefined">A Func used to validate that a value is defined.</param>
|
|
||||||
/// <param name="validate">A Func used to validate that a value is definded of throw an exception.</param>
|
|
||||||
/// <param name="undefined">An undefined value.</param>
|
|
||||||
protected EnumHelperTestBase(Func<TEnum, bool> isDefined, Action<TEnum, string> validate, TEnum undefined)
|
|
||||||
{
|
|
||||||
_isDefined = isDefined;
|
|
||||||
_validate = validate;
|
|
||||||
_undefined = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void IsDefined_ReturnsTrueForDefinedValues()
|
|
||||||
{
|
|
||||||
Array values = Enum.GetValues(typeof(TEnum));
|
|
||||||
foreach (object value in values)
|
|
||||||
{
|
|
||||||
if (ValueExistsForFramework((TEnum)value))
|
|
||||||
{
|
|
||||||
Assert.True(_isDefined((TEnum)value));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert.False(_isDefined((TEnum)value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void IsDefined_ReturnsFalseForUndefinedValues()
|
|
||||||
{
|
|
||||||
Assert.False(_isDefined(_undefined));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Validate_DoesNotThrowForDefinedValues()
|
|
||||||
{
|
|
||||||
Array values = Enum.GetValues(typeof(TEnum));
|
|
||||||
foreach (object value in values)
|
|
||||||
{
|
|
||||||
if (ValueExistsForFramework((TEnum)value))
|
|
||||||
{
|
|
||||||
_validate((TEnum)value, "parameter");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Validate_ThrowsForUndefinedValues()
|
|
||||||
{
|
|
||||||
AssertForUndefinedValue(
|
|
||||||
() => _validate(_undefined, "parameter"),
|
|
||||||
"parameter",
|
|
||||||
(int)Convert.ChangeType(_undefined, typeof(int)),
|
|
||||||
typeof(TEnum),
|
|
||||||
allowDerivedExceptions: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Override this if InvalidEnumArgument is not supported in the targetted platform
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="testCode">A delegate to the code to be tested</param>
|
|
||||||
/// <param name="paramName">The name of the parameter that should throw the exception</param>
|
|
||||||
/// <param name="invalidValue">The expected invalid value that should appear in the message</param>
|
|
||||||
/// <param name="enumType">The type of the enumeration</param>
|
|
||||||
/// <param name="allowDerivedExceptions">Pass true to allow exceptions which derive from TException; pass false, otherwise</param>
|
|
||||||
protected virtual void AssertForUndefinedValue(Action testCode, string parameterName, int invalidValue, Type enumType, bool allowDerivedExceptions = false)
|
|
||||||
{
|
|
||||||
Assert.ThrowsInvalidEnumArgument(
|
|
||||||
testCode,
|
|
||||||
parameterName,
|
|
||||||
invalidValue,
|
|
||||||
enumType,
|
|
||||||
allowDerivedExceptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Override this to determine if a given enum value for an enum exists in a given framework
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value"></param>
|
|
||||||
/// <returns>Wheter the value exists</returns>
|
|
||||||
protected virtual bool ValueExistsForFramework(TEnum value)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public class ForceGCAttribute : Xunit.BeforeAfterTestAttribute
|
|
||||||
{
|
|
||||||
public override void After(MethodInfo methodUnderTest)
|
|
||||||
{
|
|
||||||
GC.Collect(99);
|
|
||||||
GC.Collect(99);
|
|
||||||
GC.Collect(99);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics.Contracts;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public class MatrixTheoryDataSet<T1, T2> : TheoryDataSet<T1, T2>
|
|
||||||
{
|
|
||||||
public MatrixTheoryDataSet(IEnumerable<T1> data1, IEnumerable<T2> data2)
|
|
||||||
{
|
|
||||||
Contract.Assert(data1 != null && data1.Any());
|
|
||||||
Contract.Assert(data2 != null && data2.Any());
|
|
||||||
|
|
||||||
foreach (T1 t1 in data1)
|
|
||||||
{
|
|
||||||
foreach (T2 t2 in data2)
|
|
||||||
{
|
|
||||||
Add(t1, t2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,383 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.TestCommon;
|
|
||||||
|
|
||||||
namespace System.Web.TestUtil
|
|
||||||
{
|
|
||||||
public static class MemberHelper
|
|
||||||
{
|
|
||||||
private static ConstructorInfo GetConstructorInfo(object instance, Type[] parameterTypes)
|
|
||||||
{
|
|
||||||
if (instance == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("instance");
|
|
||||||
}
|
|
||||||
ConstructorInfo constructorInfo = instance.GetType().GetConstructor(parameterTypes);
|
|
||||||
if (constructorInfo == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(String.Format(
|
|
||||||
"A matching constructor on type '{0}' could not be found.",
|
|
||||||
instance.GetType().FullName));
|
|
||||||
}
|
|
||||||
return constructorInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static EventInfo GetEventInfo(object instance, string eventName)
|
|
||||||
{
|
|
||||||
if (instance == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("instance");
|
|
||||||
}
|
|
||||||
if (String.IsNullOrEmpty(eventName))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("An event must be specified.", "eventName");
|
|
||||||
}
|
|
||||||
EventInfo eventInfo = instance.GetType().GetEvent(eventName);
|
|
||||||
if (eventInfo == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(String.Format(
|
|
||||||
"An event named '{0}' on type '{1}' could not be found.",
|
|
||||||
eventName, instance.GetType().FullName));
|
|
||||||
}
|
|
||||||
return eventInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MethodInfo GetMethodInfo(object instance, string methodName, Type[] types = null, MethodAttributes attrs = MethodAttributes.Public)
|
|
||||||
{
|
|
||||||
if (instance == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("instance");
|
|
||||||
}
|
|
||||||
if (String.IsNullOrEmpty(methodName))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("A method must be specified.", "methodName");
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodInfo methodInfo;
|
|
||||||
if (types != null)
|
|
||||||
{
|
|
||||||
methodInfo = instance.GetType().GetMethod(methodName,
|
|
||||||
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
|
|
||||||
null,
|
|
||||||
types,
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
methodInfo = instance.GetType().GetMethod(methodName,
|
|
||||||
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (methodInfo == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(String.Format(
|
|
||||||
"A method named '{0}' on type '{1}' could not be found.",
|
|
||||||
methodName, instance.GetType().FullName));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((methodInfo.Attributes & attrs) != attrs)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(String.Format(
|
|
||||||
"Method '{0}' on type '{1}' with attributes '{2}' does not match the attributes '{3}'.",
|
|
||||||
methodName, instance.GetType().FullName, methodInfo.Attributes, attrs));
|
|
||||||
}
|
|
||||||
|
|
||||||
return methodInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PropertyInfo GetPropertyInfo(object instance, string propertyName)
|
|
||||||
{
|
|
||||||
if (instance == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("instance");
|
|
||||||
}
|
|
||||||
if (String.IsNullOrEmpty(propertyName))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("A property must be specified.", "propertyName");
|
|
||||||
}
|
|
||||||
PropertyInfo propInfo = instance.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
|
||||||
if (propInfo == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(String.Format(
|
|
||||||
"A property named '{0}' on type '{1}' could not be found.",
|
|
||||||
propertyName, instance.GetType().FullName));
|
|
||||||
}
|
|
||||||
return propInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void TestAttribute<TAttribute>(MemberInfo memberInfo, TAttribute attributeValue)
|
|
||||||
where TAttribute : Attribute
|
|
||||||
{
|
|
||||||
object[] attrs = memberInfo.GetCustomAttributes(typeof(TAttribute), true);
|
|
||||||
|
|
||||||
if (attributeValue == null)
|
|
||||||
{
|
|
||||||
Assert.True(attrs.Length == 0, "Member should not have an attribute of type " + typeof(TAttribute));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert.True(attrs != null && attrs.Length > 0,
|
|
||||||
"Member does not have an attribute of type " + typeof(TAttribute));
|
|
||||||
Assert.Equal(attributeValue, attrs[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestBooleanProperty(object instance, string propertyName, bool initialValue, bool testDefaultValue)
|
|
||||||
{
|
|
||||||
// Assert initial value
|
|
||||||
TestGetPropertyValue(instance, propertyName, initialValue);
|
|
||||||
|
|
||||||
if (testDefaultValue)
|
|
||||||
{
|
|
||||||
// Assert DefaultValue attribute matches inital value
|
|
||||||
TestDefaultValue(instance, propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
TestPropertyValue(instance, propertyName, true);
|
|
||||||
TestPropertyValue(instance, propertyName, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestDefaultValue(object instance, string propertyName)
|
|
||||||
{
|
|
||||||
PropertyInfo propInfo = GetPropertyInfo(instance, propertyName);
|
|
||||||
|
|
||||||
object initialValue = propInfo.GetValue(instance, null);
|
|
||||||
TestAttribute(propInfo, new DefaultValueAttribute(initialValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestEvent<TEventArgs>(object instance, string eventName, TEventArgs eventArgs) where TEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
EventInfo eventInfo = GetEventInfo(instance, eventName);
|
|
||||||
|
|
||||||
// Assert category "Action"
|
|
||||||
TestAttribute(eventInfo, new CategoryAttribute("Action"));
|
|
||||||
|
|
||||||
// Call protected method with no event handlers, assert no error
|
|
||||||
MethodInfo methodInfo = GetMethodInfo(instance, "On" + eventName, attrs: MethodAttributes.Family | MethodAttributes.Virtual);
|
|
||||||
methodInfo.Invoke(instance, new object[] { eventArgs });
|
|
||||||
|
|
||||||
// Attach handler, call method, assert fires once
|
|
||||||
List<object> eventHandlerArgs = new List<object>();
|
|
||||||
EventHandler<TEventArgs> handler = new EventHandler<TEventArgs>(delegate(object sender, TEventArgs t)
|
|
||||||
{
|
|
||||||
eventHandlerArgs.Add(sender);
|
|
||||||
eventHandlerArgs.Add(t);
|
|
||||||
});
|
|
||||||
eventInfo.AddEventHandler(instance, handler);
|
|
||||||
methodInfo.Invoke(instance, new object[] { eventArgs });
|
|
||||||
Assert.Equal(new[] { instance, eventArgs }, eventHandlerArgs.ToArray());
|
|
||||||
|
|
||||||
// Detach handler, call method, assert not fired
|
|
||||||
eventHandlerArgs = new List<object>();
|
|
||||||
eventInfo.RemoveEventHandler(instance, handler);
|
|
||||||
methodInfo.Invoke(instance, new object[] { eventArgs });
|
|
||||||
Assert.Empty(eventHandlerArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestGetPropertyValue(object instance, string propertyName, object valueToCheck)
|
|
||||||
{
|
|
||||||
PropertyInfo propInfo = GetPropertyInfo(instance, propertyName);
|
|
||||||
object value = propInfo.GetValue(instance, null);
|
|
||||||
Assert.Equal(valueToCheck, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestEnumProperty<TEnumValue>(object instance, string propertyName, TEnumValue initialValue, bool testDefaultValue)
|
|
||||||
{
|
|
||||||
// Assert initial value
|
|
||||||
TestGetPropertyValue(instance, propertyName, initialValue);
|
|
||||||
|
|
||||||
if (testDefaultValue)
|
|
||||||
{
|
|
||||||
// Assert DefaultValue attribute matches inital value
|
|
||||||
TestDefaultValue(instance, propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyInfo propInfo = GetPropertyInfo(instance, propertyName);
|
|
||||||
|
|
||||||
// Values are sorted numerically
|
|
||||||
TEnumValue[] values = (TEnumValue[])Enum.GetValues(propInfo.PropertyType);
|
|
||||||
|
|
||||||
// Assert get/set works for all valid enum values
|
|
||||||
foreach (TEnumValue value in values)
|
|
||||||
{
|
|
||||||
TestPropertyValue(instance, propertyName, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assert ArgumentOutOfRangeException is thrown for value one less than smallest
|
|
||||||
// enum value, and one more than largest enum value
|
|
||||||
var targetException = Assert.Throws<TargetInvocationException>(() => propInfo.SetValue(instance, Convert.ToInt32(values[0]) - 1, null));
|
|
||||||
Assert.IsType<ArgumentOutOfRangeException>(targetException.InnerException);
|
|
||||||
|
|
||||||
targetException = Assert.Throws<TargetInvocationException>(() => propInfo.SetValue(instance, Convert.ToInt32(values[values.Length - 1]) + 1, null));
|
|
||||||
Assert.IsType<ArgumentOutOfRangeException>(targetException.InnerException);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestInt32Property(object instance, string propertyName, int value1, int value2)
|
|
||||||
{
|
|
||||||
TestPropertyValue(instance, propertyName, value1);
|
|
||||||
TestPropertyValue(instance, propertyName, value2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestPropertyWithDefaultInstance(object instance, string propertyName, object valueToSet)
|
|
||||||
{
|
|
||||||
PropertyInfo propInfo = GetPropertyInfo(instance, propertyName);
|
|
||||||
|
|
||||||
// Set to explicit property
|
|
||||||
propInfo.SetValue(instance, valueToSet, null);
|
|
||||||
object value = propInfo.GetValue(instance, null);
|
|
||||||
Assert.Equal(valueToSet, value);
|
|
||||||
|
|
||||||
// Set to null
|
|
||||||
propInfo.SetValue(instance, null, null);
|
|
||||||
value = propInfo.GetValue(instance, null);
|
|
||||||
Assert.IsAssignableFrom(propInfo.PropertyType, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestPropertyWithDefaultInstance(object instance, string propertyName, object valueToSet, object defaultValue)
|
|
||||||
{
|
|
||||||
PropertyInfo propInfo = GetPropertyInfo(instance, propertyName);
|
|
||||||
|
|
||||||
// Set to explicit property
|
|
||||||
propInfo.SetValue(instance, valueToSet, null);
|
|
||||||
object value = propInfo.GetValue(instance, null);
|
|
||||||
Assert.Same(valueToSet, value);
|
|
||||||
|
|
||||||
// Set to null
|
|
||||||
propInfo.SetValue(instance, null, null);
|
|
||||||
value = propInfo.GetValue(instance, null);
|
|
||||||
Assert.Equal(defaultValue, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestPropertyValue(object instance, string propertyName, object value)
|
|
||||||
{
|
|
||||||
TestPropertyValue(instance, propertyName, value, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestPropertyValue(object instance, string propertyName, object valueToSet, object valueToCheck)
|
|
||||||
{
|
|
||||||
PropertyInfo propInfo = GetPropertyInfo(instance, propertyName);
|
|
||||||
propInfo.SetValue(instance, valueToSet, null);
|
|
||||||
object value = propInfo.GetValue(instance, null);
|
|
||||||
Assert.Equal(valueToCheck, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestStringParams(object instance, Type[] constructorParameterTypes, object[] parameters)
|
|
||||||
{
|
|
||||||
ConstructorInfo ctor = GetConstructorInfo(instance, constructorParameterTypes);
|
|
||||||
TestStringParams(ctor, instance, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestStringParams(object instance, string methodName, object[] parameters)
|
|
||||||
{
|
|
||||||
TestStringParams(instance, methodName, null, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestStringParams(object instance, string methodName, Type[] types, object[] parameters)
|
|
||||||
{
|
|
||||||
MethodInfo method = GetMethodInfo(instance, methodName, types);
|
|
||||||
TestStringParams(method, instance, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void TestStringParams(MethodBase method, object instance, object[] parameters)
|
|
||||||
{
|
|
||||||
ParameterInfo[] parameterInfos = method.GetParameters();
|
|
||||||
foreach (ParameterInfo parameterInfo in parameterInfos)
|
|
||||||
{
|
|
||||||
if (parameterInfo.ParameterType == typeof(String))
|
|
||||||
{
|
|
||||||
object originalParameter = parameters[parameterInfo.Position];
|
|
||||||
|
|
||||||
parameters[parameterInfo.Position] = null;
|
|
||||||
Assert.ThrowsArgumentNullOrEmpty(
|
|
||||||
delegate()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
method.Invoke(instance, parameters);
|
|
||||||
}
|
|
||||||
catch (TargetInvocationException e)
|
|
||||||
{
|
|
||||||
throw e.InnerException;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parameterInfo.Name);
|
|
||||||
|
|
||||||
parameters[parameterInfo.Position] = String.Empty;
|
|
||||||
Assert.ThrowsArgumentNullOrEmpty(
|
|
||||||
delegate()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
method.Invoke(instance, parameters);
|
|
||||||
}
|
|
||||||
catch (TargetInvocationException e)
|
|
||||||
{
|
|
||||||
throw e.InnerException;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parameterInfo.Name);
|
|
||||||
|
|
||||||
parameters[parameterInfo.Position] = originalParameter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TestStringProperty(object instance, string propertyName, string initialValue,
|
|
||||||
bool testDefaultValueAttribute = false, bool allowNullAndEmpty = true,
|
|
||||||
string nullAndEmptyReturnValue = "")
|
|
||||||
{
|
|
||||||
// Assert initial value
|
|
||||||
TestGetPropertyValue(instance, propertyName, initialValue);
|
|
||||||
|
|
||||||
if (testDefaultValueAttribute)
|
|
||||||
{
|
|
||||||
// Assert DefaultValue attribute matches inital value
|
|
||||||
TestDefaultValue(instance, propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowNullAndEmpty)
|
|
||||||
{
|
|
||||||
// Assert get/set works for null
|
|
||||||
TestPropertyValue(instance, propertyName, null, nullAndEmptyReturnValue);
|
|
||||||
|
|
||||||
// Assert get/set works for String.Empty
|
|
||||||
TestPropertyValue(instance, propertyName, String.Empty, nullAndEmptyReturnValue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert.ThrowsArgumentNullOrEmpty(
|
|
||||||
delegate()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
TestPropertyValue(instance, propertyName, null);
|
|
||||||
}
|
|
||||||
catch (TargetInvocationException e)
|
|
||||||
{
|
|
||||||
throw e.InnerException;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"value");
|
|
||||||
Assert.ThrowsArgumentNullOrEmpty(
|
|
||||||
delegate()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
TestPropertyValue(instance, propertyName, String.Empty);
|
|
||||||
}
|
|
||||||
catch (TargetInvocationException e)
|
|
||||||
{
|
|
||||||
throw e.InnerException;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"value");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assert get/set works for arbitrary value
|
|
||||||
TestPropertyValue(instance, propertyName, "TestValue");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -34,68 +34,34 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="DataAttribute.cs" />
|
<Compile Include="DataAttribute.cs" />
|
||||||
<Compile Include="EnumHelperTestBase.cs" />
|
|
||||||
<Compile Include="ExceptionAssertions.cs" />
|
<Compile Include="ExceptionAssertions.cs" />
|
||||||
|
<Compile Include="FactAttribute.cs" />
|
||||||
<Compile Include="InlineDataAttribute.cs" />
|
<Compile Include="InlineDataAttribute.cs" />
|
||||||
<Compile Include="MatrixTheoryDataSet.cs" />
|
<Compile Include="Microsoft\TestCommon\GenericTypeAssert.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\DataSets\TestDataHolder.cs" />
|
<Compile Include="Microsoft\TestCommon\MediaTypeHeaderValueComparer.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\Types\ByteEnum.cs" />
|
<Compile Include="Microsoft\TestCommon\ParsedMediaTypeHeaderValue.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\Types\SByteEnum.cs" />
|
<Compile Include="Microsoft\TestCommon\RegexReplacement.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\Types\ShortEnum.cs" />
|
<Compile Include="Microsoft\TestCommon\TimeoutConstant.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\Types\UIntEnum.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\Types\UShortEnum.cs" />
|
|
||||||
<Compile Include="Platform.cs" />
|
<Compile Include="Platform.cs" />
|
||||||
<Compile Include="PlatformInfo.cs" />
|
<Compile Include="PlatformInfo.cs" />
|
||||||
<Compile Include="PortReserver.cs" />
|
|
||||||
<Compile Include="PropertyDataAttribute.cs" />
|
<Compile Include="PropertyDataAttribute.cs" />
|
||||||
|
<Compile Include="ReflectionAssert.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="ReplaceCultureAttribute.cs" />
|
<Compile Include="ReplaceCultureAttribute.cs" />
|
||||||
<Compile Include="RestoreThreadPrincipalAttribute.cs" />
|
|
||||||
<Compile Include="Assert.cs">
|
<Compile Include="Assert.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="CultureReplacer.cs" />
|
<Compile Include="CultureReplacer.cs" />
|
||||||
<Compile Include="FactAttribute.cs" />
|
<Compile Include="TestFile.cs" />
|
||||||
<Compile Include="StringAssertions.cs" />
|
|
||||||
<Compile Include="StringAssertException.cs" />
|
|
||||||
<Compile Include="TheoryAttribute.cs" />
|
<Compile Include="TheoryAttribute.cs" />
|
||||||
<Compile Include="DictionaryEqualityComparer.cs" />
|
|
||||||
<Compile Include="ForceGCAttribute.cs" />
|
|
||||||
<Compile Include="MemberHelper.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\DataSets\RefTypeTestData.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\DataSets\TestDataVariations.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\DataSets\ValueTypeTestData.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\GenericTypeAssert.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\HttpAssert.cs" />
|
<Compile Include="Microsoft\TestCommon\HttpAssert.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\MediaTypeAssert.cs" />
|
<Compile Include="Microsoft\TestCommon\MediaTypeAssert.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\MediaTypeHeaderValueComparer.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\ParsedMediaTypeHeaderValue.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\RegexReplacement.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\RuntimeEnvironment.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\SerializerAssert.cs" />
|
<Compile Include="Microsoft\TestCommon\SerializerAssert.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\StreamAssert.cs" />
|
<Compile Include="Microsoft\TestCommon\StreamAssert.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\TaskAssert.cs" />
|
<Compile Include="Microsoft\TestCommon\TaskAssert.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\DataSets\TestData.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\TestDataSetAttribute.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\TimeoutConstant.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\TypeAssert.cs" />
|
<Compile Include="Microsoft\TestCommon\TypeAssert.cs" />
|
||||||
<Compile Include="Microsoft\TestCommon\Types\FlagsEnum.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\Types\INameAndIdContainer.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\Types\ISerializableType.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\Types\LongEnum.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\Types\SimpleEnum.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\DataSets\CommonUnitTestDataSets.cs" />
|
|
||||||
<Compile Include="Microsoft\TestCommon\XmlAssert.cs" />
|
<Compile Include="Microsoft\TestCommon\XmlAssert.cs" />
|
||||||
<Compile Include="PreAppStartTestHelper.cs" />
|
|
||||||
<Compile Include="PreserveSyncContextAttribute.cs" />
|
|
||||||
<Compile Include="ReflectionAssert.cs" />
|
|
||||||
<Compile Include="TaskExtensions.cs" />
|
|
||||||
<Compile Include="TestFile.cs" />
|
|
||||||
<Compile Include="TestHelper.cs" />
|
|
||||||
<Compile Include="TheoryDataSet.cs" />
|
|
||||||
<Compile Include="ThreadPoolSyncContext.cs" />
|
|
||||||
<Compile Include="TraitAttribute.cs" />
|
|
||||||
<Compile Include="VersionTestHelper.cs" />
|
|
||||||
<Compile Include="WebUtils.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using Microsoft.TestCommon.Types;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public class CommonUnitTestDataSets
|
|
||||||
{
|
|
||||||
public static ValueTypeTestData<char> Chars { get { return TestData.CharTestData; } }
|
|
||||||
public static ValueTypeTestData<int> Ints { get { return TestData.IntTestData; } }
|
|
||||||
public static ValueTypeTestData<uint> Uints { get { return TestData.UintTestData; } }
|
|
||||||
public static ValueTypeTestData<short> Shorts { get { return TestData.ShortTestData; } }
|
|
||||||
public static ValueTypeTestData<ushort> Ushorts { get { return TestData.UshortTestData; } }
|
|
||||||
public static ValueTypeTestData<long> Longs { get { return TestData.LongTestData; } }
|
|
||||||
public static ValueTypeTestData<ulong> Ulongs { get { return TestData.UlongTestData; } }
|
|
||||||
public static ValueTypeTestData<byte> Bytes { get { return TestData.ByteTestData; } }
|
|
||||||
public static ValueTypeTestData<sbyte> SBytes { get { return TestData.SByteTestData; } }
|
|
||||||
public static ValueTypeTestData<bool> Bools { get { return TestData.BoolTestData; } }
|
|
||||||
public static ValueTypeTestData<double> Doubles { get { return TestData.DoubleTestData; } }
|
|
||||||
public static ValueTypeTestData<float> Floats { get { return TestData.FloatTestData; } }
|
|
||||||
public static ValueTypeTestData<DateTime> DateTimes { get { return TestData.DateTimeTestData; } }
|
|
||||||
public static ValueTypeTestData<Decimal> Decimals { get { return TestData.DecimalTestData; } }
|
|
||||||
public static ValueTypeTestData<TimeSpan> TimeSpans { get { return TestData.TimeSpanTestData; } }
|
|
||||||
public static ValueTypeTestData<Guid> Guids { get { return TestData.GuidTestData; } }
|
|
||||||
public static ValueTypeTestData<DateTimeOffset> DateTimeOffsets { get { return TestData.DateTimeOffsetTestData; } }
|
|
||||||
public static ValueTypeTestData<SimpleEnum> SimpleEnums { get { return TestData.SimpleEnumTestData; } }
|
|
||||||
public static ValueTypeTestData<LongEnum> LongEnums { get { return TestData.LongEnumTestData; } }
|
|
||||||
public static ValueTypeTestData<FlagsEnum> FlagsEnums { get { return TestData.FlagsEnumTestData; } }
|
|
||||||
public static TestData<string> EmptyStrings { get { return TestData.EmptyStrings; } }
|
|
||||||
public static RefTypeTestData<string> Strings { get { return TestData.StringTestData; } }
|
|
||||||
public static TestData<string> NonNullEmptyStrings { get { return TestData.NonNullEmptyStrings; } }
|
|
||||||
public static RefTypeTestData<ISerializableType> ISerializableTypes { get { return TestData.ISerializableTypeTestData; } }
|
|
||||||
public static ReadOnlyCollection<TestData> ValueTypeTestDataCollection { get { return TestData.ValueTypeTestDataCollection; } }
|
|
||||||
public static ReadOnlyCollection<TestData> RefTypeTestDataCollection { get { return TestData.RefTypeTestDataCollection; } }
|
|
||||||
public static ReadOnlyCollection<TestData> ValueAndRefTypeTestDataCollection { get { return TestData.ValueAndRefTypeTestDataCollection; } }
|
|
||||||
public static ReadOnlyCollection<TestData> RepresentativeValueAndRefTypeTestDataCollection { get { return TestData.RepresentativeValueAndRefTypeTestDataCollection; } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public class RefTypeTestData<T> : TestData<T> where T : class
|
|
||||||
{
|
|
||||||
private Func<IEnumerable<T>> testDataProvider;
|
|
||||||
private Func<IEnumerable<T>> derivedTypeTestDataProvider;
|
|
||||||
private Func<IEnumerable<T>> knownTypeTestDataProvider;
|
|
||||||
|
|
||||||
public RefTypeTestData(Func<IEnumerable<T>> testDataProvider)
|
|
||||||
{
|
|
||||||
if (testDataProvider == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("testDataProvider");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.testDataProvider = testDataProvider;
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.WithNull, this.Type, GetNullTestData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RefTypeTestData(
|
|
||||||
Func<IEnumerable<T>> testDataProvider,
|
|
||||||
Func<IEnumerable<T>> derivedTypeTestDataProvider,
|
|
||||||
Func<IEnumerable<T>> knownTypeTestDataProvider)
|
|
||||||
: this(testDataProvider)
|
|
||||||
{
|
|
||||||
this.derivedTypeTestDataProvider = derivedTypeTestDataProvider;
|
|
||||||
if (this.derivedTypeTestDataProvider != null)
|
|
||||||
{
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsDerivedType, this.Type, this.GetTestDataAsDerivedType);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.knownTypeTestDataProvider = knownTypeTestDataProvider;
|
|
||||||
if (this.knownTypeTestDataProvider != null)
|
|
||||||
{
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsKnownType, this.Type, this.GetTestDataAsDerivedKnownType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T GetNullTestData()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<T> GetTestDataAsDerivedType()
|
|
||||||
{
|
|
||||||
if (this.derivedTypeTestDataProvider != null)
|
|
||||||
{
|
|
||||||
return this.derivedTypeTestDataProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Enumerable.Empty<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<T> GetTestDataAsDerivedKnownType()
|
|
||||||
{
|
|
||||||
if (this.knownTypeTestDataProvider != null)
|
|
||||||
{
|
|
||||||
return this.knownTypeTestDataProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Enumerable.Empty<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IEnumerable<T> GetTypedTestData()
|
|
||||||
{
|
|
||||||
return this.testDataProvider();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,463 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.TestCommon.Types;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A base class for test data. A <see cref="TestData"/> instance is associated with a given type, and the <see cref="TestData"/> instance can
|
|
||||||
/// provide instances of the given type to use as data in tests. The same <see cref="TestData"/> instance can also provide instances
|
|
||||||
/// of types related to the given type, such as a <see cref="List<>"/> of the type. See the <see cref="TestDataVariations"/> enum for all the
|
|
||||||
/// variations of test data that a <see cref="TestData"/> instance can provide.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class TestData
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="char"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<char> CharTestData = new ValueTypeTestData<char>('a', Char.MinValue, Char.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="int"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<int> IntTestData = new ValueTypeTestData<int>(-1, 0, 1, Int32.MinValue, Int32.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="uint"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<uint> UintTestData = new ValueTypeTestData<uint>(0, 1, UInt32.MinValue, UInt32.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="short"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<short> ShortTestData = new ValueTypeTestData<short>(-1, 0, 1, Int16.MinValue, Int16.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="ushort"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<ushort> UshortTestData = new ValueTypeTestData<ushort>(0, 1, UInt16.MinValue, UInt16.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="long"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<long> LongTestData = new ValueTypeTestData<long>(-1, 0, 1, Int64.MinValue, Int64.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="ulong"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<ulong> UlongTestData = new ValueTypeTestData<ulong>(0, 1, UInt64.MinValue, UInt64.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="byte"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<byte> ByteTestData = new ValueTypeTestData<byte>(0, 1, Byte.MinValue, Byte.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="sbyte"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<sbyte> SByteTestData = new ValueTypeTestData<sbyte>(-1, 0, 1, SByte.MinValue, SByte.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="bool"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<bool> BoolTestData = new ValueTypeTestData<bool>(true, false);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="double"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<double> DoubleTestData = new ValueTypeTestData<double>(
|
|
||||||
-1.0,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
double.MinValue,
|
|
||||||
double.MaxValue,
|
|
||||||
double.PositiveInfinity,
|
|
||||||
double.NegativeInfinity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="float"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<float> FloatTestData = new ValueTypeTestData<float>(
|
|
||||||
-1.0f,
|
|
||||||
0.0f,
|
|
||||||
1.0f,
|
|
||||||
float.MinValue,
|
|
||||||
float.MaxValue,
|
|
||||||
float.PositiveInfinity,
|
|
||||||
float.NegativeInfinity);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="decimal"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<decimal> DecimalTestData = new ValueTypeTestData<decimal>(
|
|
||||||
-1M,
|
|
||||||
0M,
|
|
||||||
1M,
|
|
||||||
decimal.MinValue,
|
|
||||||
decimal.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="DateTime"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<DateTime> DateTimeTestData = new ValueTypeTestData<DateTime>(
|
|
||||||
DateTime.Now,
|
|
||||||
DateTime.UtcNow,
|
|
||||||
DateTime.MaxValue,
|
|
||||||
DateTime.MinValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="TimeSpan"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<TimeSpan> TimeSpanTestData = new ValueTypeTestData<TimeSpan>(
|
|
||||||
TimeSpan.MinValue,
|
|
||||||
TimeSpan.MaxValue);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="Guid"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<Guid> GuidTestData = new ValueTypeTestData<Guid>(
|
|
||||||
Guid.NewGuid(),
|
|
||||||
Guid.Empty);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="DateTimeOffset"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<DateTimeOffset> DateTimeOffsetTestData = new ValueTypeTestData<DateTimeOffset>(
|
|
||||||
DateTimeOffset.MaxValue,
|
|
||||||
DateTimeOffset.MinValue,
|
|
||||||
new DateTimeOffset(DateTime.Now));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for an <c>enum</c>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<SimpleEnum> SimpleEnumTestData = new ValueTypeTestData<SimpleEnum>(
|
|
||||||
SimpleEnum.First,
|
|
||||||
SimpleEnum.Second,
|
|
||||||
SimpleEnum.Third);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for an <c>enum</c> implemented with a <see cref="long"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<LongEnum> LongEnumTestData = new ValueTypeTestData<LongEnum>(
|
|
||||||
LongEnum.FirstLong,
|
|
||||||
LongEnum.SecondLong,
|
|
||||||
LongEnum.ThirdLong);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for an <c>enum</c> decorated with a <see cref="FlagsAttribtute"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ValueTypeTestData<FlagsEnum> FlagsEnumTestData = new ValueTypeTestData<FlagsEnum>(
|
|
||||||
FlagsEnum.One,
|
|
||||||
FlagsEnum.Two,
|
|
||||||
FlagsEnum.Four);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Expected permutations of non supported file paths.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly TestData<string> NotSupportedFilePaths = new RefTypeTestData<string>(() => new List<string>() {
|
|
||||||
"cc:\\a\\b",
|
|
||||||
});
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Expected permutations of invalid file paths.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly TestData<string> InvalidNonNullFilePaths = new RefTypeTestData<string>(() => new List<string>() {
|
|
||||||
String.Empty,
|
|
||||||
"",
|
|
||||||
" ",
|
|
||||||
" ",
|
|
||||||
"\t\t \n ",
|
|
||||||
"c:\\a<b",
|
|
||||||
"c:\\a>b",
|
|
||||||
"c:\\a\"b",
|
|
||||||
"c:\\a\tb",
|
|
||||||
"c:\\a|b",
|
|
||||||
"c:\\a\bb",
|
|
||||||
"c:\\a\0b",
|
|
||||||
});
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All expected permutations of an empty string.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly TestData<string> NonNullEmptyStrings = new RefTypeTestData<string>(() => new List<string>() { String.Empty, "", " ", "\t\r\n" });
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All expected permutations of an empty string.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly TestData<string> EmptyStrings = new RefTypeTestData<string>(() => new List<string>() { null, String.Empty, "", " ", "\t\r\n" });
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a <see cref="string"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly RefTypeTestData<string> StringTestData = new RefTypeTestData<string>(() => new List<string>() {
|
|
||||||
"",
|
|
||||||
" ", // one space
|
|
||||||
" ", // multiple spaces
|
|
||||||
" data ", // leading and trailing whitespace
|
|
||||||
"\t\t \n ",
|
|
||||||
"Some String!"});
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Common <see cref="TestData"/> for a class that implements <see cref="ISerializable"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly RefTypeTestData<ISerializableType> ISerializableTypeTestData = new RefTypeTestData<ISerializableType>(
|
|
||||||
ISerializableType.GetTestData);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A read-only collection of value type test data.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ReadOnlyCollection<TestData> ValueTypeTestDataCollection = new ReadOnlyCollection<TestData>(new TestData[] {
|
|
||||||
CharTestData,
|
|
||||||
IntTestData,
|
|
||||||
UintTestData,
|
|
||||||
ShortTestData,
|
|
||||||
UshortTestData,
|
|
||||||
LongTestData,
|
|
||||||
UlongTestData,
|
|
||||||
ByteTestData,
|
|
||||||
SByteTestData,
|
|
||||||
BoolTestData,
|
|
||||||
DoubleTestData,
|
|
||||||
FloatTestData,
|
|
||||||
DecimalTestData,
|
|
||||||
TimeSpanTestData,
|
|
||||||
GuidTestData,
|
|
||||||
DateTimeOffsetTestData,
|
|
||||||
SimpleEnumTestData,
|
|
||||||
LongEnumTestData,
|
|
||||||
FlagsEnumTestData});
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A read-only collection of reference type test data.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ReadOnlyCollection<TestData> RefTypeTestDataCollection = new ReadOnlyCollection<TestData>(new TestData[] {
|
|
||||||
StringTestData,
|
|
||||||
ISerializableTypeTestData});
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A read-only collection of value and reference type test data.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ReadOnlyCollection<TestData> ValueAndRefTypeTestDataCollection = new ReadOnlyCollection<TestData>(
|
|
||||||
ValueTypeTestDataCollection.Concat(RefTypeTestDataCollection).ToList());
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A read-only collection of representative values and reference type test data.
|
|
||||||
/// Uses where exhaustive coverage is not required.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly ReadOnlyCollection<TestData> RepresentativeValueAndRefTypeTestDataCollection = new ReadOnlyCollection<TestData>(new TestData[] {
|
|
||||||
IntTestData,
|
|
||||||
BoolTestData,
|
|
||||||
SimpleEnumTestData,
|
|
||||||
StringTestData,
|
|
||||||
});
|
|
||||||
|
|
||||||
private Dictionary<TestDataVariations, TestDataVariationProvider> registeredTestDataVariations;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="TestData"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The type associated with the <see cref="TestData"/> instance.</param>
|
|
||||||
protected TestData(Type type)
|
|
||||||
{
|
|
||||||
if (type.ContainsGenericParameters)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Only closed generic types are supported.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Type = type;
|
|
||||||
this.registeredTestDataVariations = new Dictionary<TestDataVariations, TestDataVariationProvider>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the type associated with the <see cref="TestData"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
public Type Type { get; private set; }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the supported test data variations.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IEnumerable<TestDataVariations> GetSupportedTestDataVariations()
|
|
||||||
{
|
|
||||||
return this.registeredTestDataVariations.Keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the related type for the given test data variation or returns null if the <see cref="TestData"/> instance
|
|
||||||
/// doesn't support the given variation.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="variation">The test data variation with which to create the related <see cref="Type"/>.</param>
|
|
||||||
/// <returns>The related <see cref="Type"/> for the <see cref="TestData.Type"/> as given by the test data variation.</returns>
|
|
||||||
/// <example>
|
|
||||||
/// For example, if the given <see cref="TestData"/> was created for <see cref="string"/> test data and the varation parameter
|
|
||||||
/// was <see cref="TestDataVariations.AsList"/> then the returned type would be <see cref="List<string>"/>.
|
|
||||||
/// </example>
|
|
||||||
public Type GetAsTypeOrNull(TestDataVariations variation)
|
|
||||||
{
|
|
||||||
TestDataVariationProvider testDataVariation = null;
|
|
||||||
if (this.registeredTestDataVariations.TryGetValue(variation, out testDataVariation))
|
|
||||||
{
|
|
||||||
return testDataVariation.Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets test data for the given test data variation or returns null if the <see cref="TestData"/> instance
|
|
||||||
/// doesn't support the given variation.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="variation">The test data variation with which to create the related test data.</param>
|
|
||||||
/// <returns>Test data of the type specified by the <see cref="TestData.GetAsTypeOrNull"/> method.</returns>
|
|
||||||
public object GetAsTestDataOrNull(TestDataVariations variation)
|
|
||||||
{
|
|
||||||
TestDataVariationProvider testDataVariation = null;
|
|
||||||
if (this.registeredTestDataVariations.TryGetValue(variation, out testDataVariation))
|
|
||||||
{
|
|
||||||
return testDataVariation.TestDataProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Allows derived classes to register a <paramref name="testDataProvider "/> <see cref="Func<>"/> that will
|
|
||||||
/// provide test data for a given variation.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="variation">The variation with which to register the <paramref name="testDataProvider "/>r.</param>
|
|
||||||
/// <param name="type">The type of the test data created by the <paramref name="testDataProvider "/></param>
|
|
||||||
/// <param name="testDataProvider">A <see cref="Func<>"/> that will provide test data.</param>
|
|
||||||
protected void RegisterTestDataVariation(TestDataVariations variation, Type type, Func<object> testDataProvider)
|
|
||||||
{
|
|
||||||
this.registeredTestDataVariations.Add(variation, new TestDataVariationProvider(type, testDataProvider));
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestDataVariationProvider
|
|
||||||
{
|
|
||||||
public TestDataVariationProvider(Type type, Func<object> testDataProvider)
|
|
||||||
{
|
|
||||||
this.Type = type;
|
|
||||||
this.TestDataProvider = testDataProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Func<object> TestDataProvider { get; private set; }
|
|
||||||
|
|
||||||
public Type Type { get; private set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A generic base class for test data.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type associated with the test data.</typeparam>
|
|
||||||
public abstract class TestData<T> : TestData, IEnumerable<T>
|
|
||||||
{
|
|
||||||
private static readonly Type OpenIEnumerableType = typeof(IEnumerable<>);
|
|
||||||
private static readonly Type OpenListType = typeof(List<>);
|
|
||||||
private static readonly Type OpenIQueryableType = typeof(IQueryable<>);
|
|
||||||
private static readonly Type OpenDictionaryType = typeof(Dictionary<,>);
|
|
||||||
private static readonly Type OpenTestDataHolderType = typeof(TestDataHolder<>);
|
|
||||||
private int dictionaryKey;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="TestData<T>"/> class.
|
|
||||||
/// </summary>
|
|
||||||
protected TestData()
|
|
||||||
: base(typeof(T))
|
|
||||||
{
|
|
||||||
Type[] typeParams = new Type[] { this.Type };
|
|
||||||
Type[] dictionaryTypeParams = new Type[] { typeof(string), this.Type };
|
|
||||||
|
|
||||||
Type arrayType = this.Type.MakeArrayType();
|
|
||||||
Type listType = OpenListType.MakeGenericType(typeParams);
|
|
||||||
Type iEnumerableType = OpenIEnumerableType.MakeGenericType(typeParams);
|
|
||||||
Type iQueryableType = OpenIQueryableType.MakeGenericType(typeParams);
|
|
||||||
Type dictionaryType = OpenDictionaryType.MakeGenericType(dictionaryTypeParams);
|
|
||||||
Type testDataHolderType = OpenTestDataHolderType.MakeGenericType(typeParams);
|
|
||||||
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsInstance, this.Type, () => GetTypedTestData());
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsArray, arrayType, GetTestDataAsArray);
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsIEnumerable, iEnumerableType, GetTestDataAsIEnumerable);
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsIQueryable, iQueryableType, GetTestDataAsIQueryable);
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsList, listType, GetTestDataAsList);
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsDictionary, dictionaryType, GetTestDataAsDictionary);
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsClassMember, testDataHolderType, GetTestDataInHolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<T> GetEnumerator()
|
|
||||||
{
|
|
||||||
return (IEnumerator<T>)this.GetTypedTestData().ToList().GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return (IEnumerator)this.GetTypedTestData().ToList().GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the test data as an array.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>An array of test data of the given type.</returns>
|
|
||||||
public T[] GetTestDataAsArray()
|
|
||||||
{
|
|
||||||
return this.GetTypedTestData().ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the test data as a <see cref="List<>"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A <see cref="List<>"/> of test data of the given type.</returns>
|
|
||||||
public List<T> GetTestDataAsList()
|
|
||||||
{
|
|
||||||
return this.GetTypedTestData().ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the test data as an <see cref="IEnumerable<>"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>An <see cref="IEnumerable<>"/> of test data of the given type.</returns>
|
|
||||||
public IEnumerable<T> GetTestDataAsIEnumerable()
|
|
||||||
{
|
|
||||||
return this.GetTypedTestData().AsEnumerable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the test data as an <see cref="IQueryable<>"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>An <see cref="IQueryable<>"/> of test data of the given type.</returns>
|
|
||||||
public IQueryable<T> GetTestDataAsIQueryable()
|
|
||||||
{
|
|
||||||
return this.GetTypedTestData().AsQueryable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, T> GetTestDataAsDictionary()
|
|
||||||
{
|
|
||||||
// Some TestData collections contain duplicates e.g. UintTestData contains both 0 and UInt32.MinValue.
|
|
||||||
// Therefore use dictionaryKey, not _unused.ToString(). Reset key to keep dictionaries consistent if used
|
|
||||||
// multiple times.
|
|
||||||
dictionaryKey = 0;
|
|
||||||
return this.GetTypedTestData().ToDictionary(_unused => (dictionaryKey++).ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<TestDataHolder<T>> GetTestDataInHolder()
|
|
||||||
{
|
|
||||||
return this.GetTypedTestData().Select(value => new TestDataHolder<T> { V1 = value, });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Must be implemented by derived types to return test data of the given type.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Test data of the given type.</returns>
|
|
||||||
protected abstract IEnumerable<T> GetTypedTestData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Equatable class wrapping a single instance of type <paramref name="T"/>. Equatable to ease test assertions.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The <see cref="Type"/> to wrap.</typeparam>
|
|
||||||
public class TestDataHolder<T> : IEquatable<TestDataHolder<T>>
|
|
||||||
{
|
|
||||||
public T V1 { get; set; }
|
|
||||||
|
|
||||||
bool IEquatable<TestDataHolder<T>>.Equals(TestDataHolder<T> other)
|
|
||||||
{
|
|
||||||
if (other == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Object.Equals(V1, other.V1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
TestDataHolder<T> that = obj as TestDataHolder<T>;
|
|
||||||
return ((IEquatable<TestDataHolder<T>>)this).Equals(that);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
if (typeof(ValueType).IsAssignableFrom(typeof(T)) || V1 != null)
|
|
||||||
{
|
|
||||||
return V1.GetHashCode();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return String.Format(CultureInfo.InvariantCulture, "{{ V1: '{0}' }}", V1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An flags enum that can be used to indicate different variations of a given
|
|
||||||
/// <see cref="TestData"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
[Flags]
|
|
||||||
public enum TestDataVariations
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An individual instance of a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AsInstance = 0x1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An individual instance of a type that derives from a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AsDerivedType = 0x2,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An individual instance of a given <see cref="TestData"/> type that has a property value
|
|
||||||
/// that is a known type of the declared property type.
|
|
||||||
/// </summary>
|
|
||||||
AsKnownType = 0x4,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A <see cref="Nullable<>"/> instance of a given <see cref="TestData"/> type. Only applies to
|
|
||||||
/// instances of <see cref="ValueTypeTestData"/>.
|
|
||||||
/// </summary>
|
|
||||||
AsNullable = 0x8,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An instance of a <see cref="System.Collections.Generic.List<>"/> of a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AsList = 0x10,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An instance of a array of the <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AsArray = 0x20,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An instance of an <see cref="System.Collections.Generic.IEnumerable<>"/> of a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AsIEnumerable = 0x40,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An instance of an <see cref="System.Linq.IQueryable<>"/> of a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AsIQueryable = 0x80,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An instance of a DataContract type in which a given <see cref="TestData"/> type is a member.
|
|
||||||
/// </summary>
|
|
||||||
AsDataMember = 0x100,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An instance of a type in which a given <see cref="TestData"/> type is decorated with a
|
|
||||||
/// <see cref="System.Xml.Serialization.XmlElementAttribute"/>.
|
|
||||||
/// </summary>
|
|
||||||
AsXmlElementProperty = 0x200,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An instance of a <see cref="System.Collections.Generic.IDictionary{string,TValue}"/> of a given
|
|
||||||
/// <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AsDictionary = 0x400,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add a <c>null</c> instance of the given <see cref="TestData"/> type to the data set. This variation is
|
|
||||||
/// not included in <see cref="All"/> or other variation masks.
|
|
||||||
/// </summary>
|
|
||||||
WithNull = 0x800,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Individual instances of <see cref="TestDataHolder{T}"/> containing the given <see cref="TestData"/>. This
|
|
||||||
/// variation is not included in <see cref="All"/> or other variation masks.
|
|
||||||
/// </summary>
|
|
||||||
AsClassMember = 0x1000,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All of the flags for single instance variations of a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AllSingleInstances = AsInstance | AsDerivedType | AsKnownType | AsNullable,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All of the flags for collection variations of a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AllCollections = AsList | AsArray | AsIEnumerable | AsIQueryable | AsDictionary,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All of the flags for variations in which a given <see cref="TestData"/> type is a property on another type.
|
|
||||||
/// </summary>
|
|
||||||
AllProperties = AsDataMember | AsXmlElementProperty,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All of the flags for interface collection variations of a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AllInterfaces = AsIEnumerable | AsIQueryable,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All of the flags except for the interface collection variations of a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
AllNonInterfaces = All & ~AllInterfaces,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All of the flags for all of the variations of a given <see cref="TestData"/> type.
|
|
||||||
/// </summary>
|
|
||||||
All = AllSingleInstances | AllCollections | AllProperties
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public class ValueTypeTestData<T> : TestData<T> where T : struct
|
|
||||||
{
|
|
||||||
private static readonly Type OpenNullableType = typeof(Nullable<>);
|
|
||||||
private T[] testData;
|
|
||||||
|
|
||||||
public ValueTypeTestData(params T[] testData)
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
this.testData = testData;
|
|
||||||
|
|
||||||
Type[] typeParams = new Type[] { this.Type };
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.WithNull, OpenNullableType.MakeGenericType(typeParams), GetNullTestData);
|
|
||||||
this.RegisterTestDataVariation(TestDataVariations.AsNullable, OpenNullableType.MakeGenericType(typeParams), GetTestDataAsNullable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public object GetNullTestData()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Nullable<T>> GetTestDataAsNullable()
|
|
||||||
{
|
|
||||||
return this.GetTypedTestData().Select(d => new Nullable<T>(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IEnumerable<T> GetTypedTestData()
|
|
||||||
{
|
|
||||||
return this.testData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public static class RuntimeEnvironment
|
|
||||||
{
|
|
||||||
private const string NetFx40FullSubKey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full";
|
|
||||||
private const string Version = "Version";
|
|
||||||
|
|
||||||
static RuntimeEnvironment()
|
|
||||||
{
|
|
||||||
object runtimeVersion = Registry.LocalMachine.OpenSubKey(RuntimeEnvironment.NetFx40FullSubKey).GetValue(RuntimeEnvironment.Version);
|
|
||||||
string versionFor40String = runtimeVersion as string;
|
|
||||||
if (versionFor40String != null)
|
|
||||||
{
|
|
||||||
VersionFor40 = new Version(versionFor40String);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Version VersionFor40;
|
|
||||||
|
|
||||||
public static bool IsVersion45Installed
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return VersionFor40.Major > 4 || (VersionFor40.Major == 4 && VersionFor40.Minor >= 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,203 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public class TestDataSetAttribute : DataAttribute
|
|
||||||
{
|
|
||||||
public Type DeclaringType { get; set; }
|
|
||||||
|
|
||||||
public string PropertyName { get; set; }
|
|
||||||
|
|
||||||
public TestDataVariations TestDataVariations { get; set; }
|
|
||||||
|
|
||||||
private IEnumerable<Tuple<Type, string>> ExtraDataSets { get; set; }
|
|
||||||
|
|
||||||
public TestDataSetAttribute(Type declaringType, string propertyName, TestDataVariations testDataVariations = TestCommon.TestDataVariations.All)
|
|
||||||
{
|
|
||||||
DeclaringType = declaringType;
|
|
||||||
PropertyName = propertyName;
|
|
||||||
TestDataVariations = testDataVariations;
|
|
||||||
ExtraDataSets = new List<Tuple<Type, string>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestDataSetAttribute(Type declaringType, string propertyName,
|
|
||||||
Type declaringType1, string propertyName1,
|
|
||||||
TestDataVariations testDataVariations = TestCommon.TestDataVariations.All)
|
|
||||||
: this(declaringType, propertyName, testDataVariations)
|
|
||||||
{
|
|
||||||
ExtraDataSets = new List<Tuple<Type, string>> { Tuple.Create(declaringType1, propertyName1) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestDataSetAttribute(Type declaringType, string propertyName,
|
|
||||||
Type declaringType1, string propertyName1,
|
|
||||||
Type declaringType2, string propertyName2,
|
|
||||||
TestDataVariations testDataVariations = TestCommon.TestDataVariations.All)
|
|
||||||
: this(declaringType, propertyName, testDataVariations)
|
|
||||||
{
|
|
||||||
ExtraDataSets = new List<Tuple<Type, string>> { Tuple.Create(declaringType1, propertyName1), Tuple.Create(declaringType2, propertyName2) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestDataSetAttribute(Type declaringType, string propertyName,
|
|
||||||
Type declaringType1, string propertyName1,
|
|
||||||
Type declaringType2, string propertyName2,
|
|
||||||
Type declaringType3, string propertyName3,
|
|
||||||
TestDataVariations testDataVariations = TestCommon.TestDataVariations.All)
|
|
||||||
: this(declaringType, propertyName, testDataVariations)
|
|
||||||
{
|
|
||||||
ExtraDataSets = new List<Tuple<Type, string>> { Tuple.Create(declaringType1, propertyName1), Tuple.Create(declaringType2, propertyName2), Tuple.Create(declaringType3, propertyName3) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestDataSetAttribute(Type declaringType, string propertyName,
|
|
||||||
Type declaringType1, string propertyName1,
|
|
||||||
Type declaringType2, string propertyName2,
|
|
||||||
Type declaringType3, string propertyName3,
|
|
||||||
Type declaringType4, string propertyName4,
|
|
||||||
TestDataVariations testDataVariations = TestCommon.TestDataVariations.All)
|
|
||||||
: this(declaringType, propertyName, testDataVariations)
|
|
||||||
{
|
|
||||||
ExtraDataSets = new List<Tuple<Type, string>>
|
|
||||||
{
|
|
||||||
Tuple.Create(declaringType1, propertyName1), Tuple.Create(declaringType2, propertyName2),
|
|
||||||
Tuple.Create(declaringType3, propertyName3), Tuple.Create(declaringType4, propertyName4)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<object[]> GetData(MethodInfo methodUnderTest, Type[] parameterTypes)
|
|
||||||
{
|
|
||||||
IEnumerable<object[]> baseDataSet = GetBaseDataSet(DeclaringType, PropertyName, TestDataVariations);
|
|
||||||
IEnumerable<IEnumerable<object[]>> extraDataSets = GetExtraDataSets();
|
|
||||||
|
|
||||||
IEnumerable<IEnumerable<object[]>> finalDataSets = (new[] { baseDataSet }).Concat(extraDataSets);
|
|
||||||
|
|
||||||
var datasets = CrossProduct(finalDataSets);
|
|
||||||
|
|
||||||
return datasets;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<object[]> CrossProduct(IEnumerable<IEnumerable<object[]>> datasets)
|
|
||||||
{
|
|
||||||
if (datasets.Count() == 1)
|
|
||||||
{
|
|
||||||
foreach (var dataset in datasets.First())
|
|
||||||
{
|
|
||||||
yield return dataset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IEnumerable<object[]> datasetLeft = datasets.First();
|
|
||||||
IEnumerable<object[]> datasetRight = CrossProduct(datasets.Skip(1));
|
|
||||||
|
|
||||||
foreach (var dataLeft in datasetLeft)
|
|
||||||
{
|
|
||||||
foreach (var dataRight in datasetRight)
|
|
||||||
{
|
|
||||||
yield return dataLeft.Concat(dataRight).ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The base data set(first one) can either be a TestDataSet or a TestDataSetCollection
|
|
||||||
private static IEnumerable<object[]> GetBaseDataSet(Type declaringType, string propertyName, TestDataVariations variations)
|
|
||||||
{
|
|
||||||
return TryGetDataSetFromTestDataCollection(declaringType, propertyName, variations) ?? GetDataSet(declaringType, propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<IEnumerable<object[]>> GetExtraDataSets()
|
|
||||||
{
|
|
||||||
foreach (var tuple in ExtraDataSets)
|
|
||||||
{
|
|
||||||
yield return GetDataSet(tuple.Item1, tuple.Item2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static object GetTestDataPropertyValue(Type declaringType, string propertyName)
|
|
||||||
{
|
|
||||||
PropertyInfo property = declaringType.GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public);
|
|
||||||
|
|
||||||
if (property == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException(String.Format("Could not find public static property {0} on {1}", propertyName, declaringType.FullName));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return property.GetValue(null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<object[]> GetDataSet(Type declaringType, string propertyName)
|
|
||||||
{
|
|
||||||
object propertyValue = GetTestDataPropertyValue(declaringType, propertyName);
|
|
||||||
|
|
||||||
// box the dataset items if the property is not a RefTypeTestData
|
|
||||||
IEnumerable<object> value = (propertyValue as IEnumerable<object>) ?? (propertyValue as IEnumerable).Cast<object>();
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException(String.Format("{0}.{1} is either null or does not implement IEnumerable", declaringType.FullName, propertyName));
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerable<object[]> dataset = value as IEnumerable<object[]>;
|
|
||||||
if (dataset != null)
|
|
||||||
{
|
|
||||||
return dataset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return value.Select((data) => new object[] { data });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<object[]> TryGetDataSetFromTestDataCollection(Type declaringType, string propertyName, TestDataVariations variations)
|
|
||||||
{
|
|
||||||
object propertyValue = GetTestDataPropertyValue(declaringType, propertyName);
|
|
||||||
|
|
||||||
IEnumerable<TestData> testDataCollection = propertyValue as IEnumerable<TestData>;
|
|
||||||
|
|
||||||
return testDataCollection == null ? null : GetDataSetFromTestDataCollection(testDataCollection, variations);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<object[]> GetDataSetFromTestDataCollection(IEnumerable<TestData> testDataCollection, TestDataVariations variations)
|
|
||||||
{
|
|
||||||
foreach (TestData testdataInstance in testDataCollection)
|
|
||||||
{
|
|
||||||
foreach (TestDataVariations variation in testdataInstance.GetSupportedTestDataVariations())
|
|
||||||
{
|
|
||||||
if ((variation & variations) == variation)
|
|
||||||
{
|
|
||||||
Type variationType = testdataInstance.GetAsTypeOrNull(variation);
|
|
||||||
object testData = testdataInstance.GetAsTestDataOrNull(variation);
|
|
||||||
if (AsSingleInstances(variation))
|
|
||||||
{
|
|
||||||
foreach (object obj in (IEnumerable)testData)
|
|
||||||
{
|
|
||||||
yield return new object[] { variationType, obj };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
yield return new object[] { variationType, testData };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool AsSingleInstances(TestDataVariations variation)
|
|
||||||
{
|
|
||||||
return variation == TestDataVariations.AsInstance ||
|
|
||||||
variation == TestDataVariations.AsNullable ||
|
|
||||||
variation == TestDataVariations.AsDerivedType ||
|
|
||||||
variation == TestDataVariations.AsKnownType ||
|
|
||||||
variation == TestDataVariations.AsDataMember ||
|
|
||||||
variation == TestDataVariations.AsClassMember ||
|
|
||||||
variation == TestDataVariations.AsXmlElementProperty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
public enum ByteEnum : byte
|
|
||||||
{
|
|
||||||
FirstByte,
|
|
||||||
SecondByte,
|
|
||||||
ThirdByte
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
[Flags]
|
|
||||||
public enum FlagsEnum
|
|
||||||
{
|
|
||||||
One = 0x1,
|
|
||||||
Two = 0x2,
|
|
||||||
Four = 0x4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tagging interface to assist comparing instances of these types.
|
|
||||||
/// </summary>
|
|
||||||
public interface INameAndIdContainer
|
|
||||||
{
|
|
||||||
string Name { get; set; }
|
|
||||||
|
|
||||||
int Id { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
[Serializable]
|
|
||||||
public class ISerializableType : ISerializable, INameAndIdContainer
|
|
||||||
{
|
|
||||||
private int id;
|
|
||||||
private string name;
|
|
||||||
|
|
||||||
public ISerializableType()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public ISerializableType(int id, string name)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ISerializableType(SerializationInfo information, StreamingContext context)
|
|
||||||
{
|
|
||||||
this.id = information.GetInt32("Id");
|
|
||||||
this.name = information.GetString("Name");
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Id
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
this.IdSet = true;
|
|
||||||
this.id = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
this.NameSet = true;
|
|
||||||
this.name = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IdSet { get; private set; }
|
|
||||||
|
|
||||||
public bool NameSet { get; private set; }
|
|
||||||
|
|
||||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
|
||||||
{
|
|
||||||
info.AddValue("Id", this.Id);
|
|
||||||
info.AddValue("Name", this.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<ISerializableType> GetTestData()
|
|
||||||
{
|
|
||||||
return new ISerializableType[] { new ISerializableType(), new ISerializableType(1, "SomeName") };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
public enum LongEnum : long
|
|
||||||
{
|
|
||||||
FirstLong,
|
|
||||||
SecondLong,
|
|
||||||
ThirdLong,
|
|
||||||
FourthLong
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
public enum SByteEnum : sbyte
|
|
||||||
{
|
|
||||||
FirstSByte,
|
|
||||||
SecondSByte,
|
|
||||||
ThirdSByte
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
public enum ShortEnum : short
|
|
||||||
{
|
|
||||||
FirstShort,
|
|
||||||
SecondShort,
|
|
||||||
ThirdShort
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
public enum SimpleEnum
|
|
||||||
{
|
|
||||||
First,
|
|
||||||
Second,
|
|
||||||
Third,
|
|
||||||
Fourth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
public enum UIntEnum : uint
|
|
||||||
{
|
|
||||||
FirstUInt,
|
|
||||||
SecondUInt,
|
|
||||||
ThirdUInt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon.Types
|
|
||||||
{
|
|
||||||
public enum UShortEnum : ushort
|
|
||||||
{
|
|
||||||
FirstUShort,
|
|
||||||
SecondUShort,
|
|
||||||
ThirdUShort
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class allocates ports while ensuring that:
|
|
||||||
/// 1. Ports that are permanentaly taken (or taken for the duration of the test) are not being attempted to be used.
|
|
||||||
/// 2. Ports are not shared across different tests (but you can allocate two different ports in the same test).
|
|
||||||
///
|
|
||||||
/// Gotcha: If another application grabs a port during the test, we have a race condition.
|
|
||||||
/// </summary>
|
|
||||||
[DebuggerDisplay("Port: {PortNumber}, Port count for this app domain: {_appDomainOwnedPorts.Count}")]
|
|
||||||
public class PortReserver : IDisposable
|
|
||||||
{
|
|
||||||
private Mutex _portMutex;
|
|
||||||
|
|
||||||
// We use this list to hold on to all the ports used because the Mutex will be blown through on the same thread.
|
|
||||||
// Theoretically we can do a thread local hashset, but that makes dispose thread dependant, or requires more complicated concurrency checks.
|
|
||||||
// Since practically there is no perf issue or concern here, this keeps the code the simplest possible.
|
|
||||||
private static HashSet<int> _appDomainOwnedPorts = new HashSet<int>();
|
|
||||||
|
|
||||||
public int PortNumber
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PortReserver(int basePort = 50231)
|
|
||||||
{
|
|
||||||
if (basePort <= 0)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab a cross appdomain/cross process/cross thread lock, to ensure only one port is reserved at a time.
|
|
||||||
using (Mutex mutex = GetGlobalMutex())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int port = basePort - 1;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
port++;
|
|
||||||
|
|
||||||
if (port > 65535)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Exceeded port range");
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppDomainOwnedPorts check enables reserving two ports from the same thread in sequence.
|
|
||||||
// ListUsedTCPPort prevents port contention with other apps.
|
|
||||||
if (_appDomainOwnedPorts.Contains(port) ||
|
|
||||||
ListUsedTCPPort().Any(endPoint => endPoint.Port == port))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
string mutexName = "WebStack-Port-" + port.ToString(CultureInfo.InvariantCulture); // Create a well known mutex
|
|
||||||
_portMutex = new Mutex(initiallyOwned: false, name: mutexName);
|
|
||||||
|
|
||||||
// If no one else is using this port grab it.
|
|
||||||
if (_portMutex.WaitOne(millisecondsTimeout: 0))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// dispose this mutex since the port it represents is not available.
|
|
||||||
_portMutex.Dispose();
|
|
||||||
_portMutex = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
PortNumber = port;
|
|
||||||
_appDomainOwnedPorts.Add(port);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
mutex.ReleaseMutex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string BaseUri
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return String.Format(CultureInfo.InvariantCulture, "http://localhost:{0}/", PortNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (PortNumber == -1)
|
|
||||||
{
|
|
||||||
// Object already disposed
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (Mutex mutex = GetGlobalMutex())
|
|
||||||
{
|
|
||||||
_portMutex.Dispose();
|
|
||||||
_appDomainOwnedPorts.Remove(PortNumber);
|
|
||||||
PortNumber = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Mutex GetGlobalMutex()
|
|
||||||
{
|
|
||||||
Mutex mutex = new Mutex(initiallyOwned: false, name: "WebStack-RandomPortAcquisition");
|
|
||||||
if (!mutex.WaitOne(30000))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return mutex;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IPEndPoint[] ListUsedTCPPort()
|
|
||||||
{
|
|
||||||
var usedPort = new HashSet<int>();
|
|
||||||
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
|
|
||||||
|
|
||||||
return ipGlobalProperties.GetActiveTcpListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.TestCommon;
|
|
||||||
|
|
||||||
namespace System.Web.WebPages.TestUtils
|
|
||||||
{
|
|
||||||
public static class PreAppStartTestHelper
|
|
||||||
{
|
|
||||||
public static void TestPreAppStartClass(Type preAppStartType)
|
|
||||||
{
|
|
||||||
string typeMessage = String.Format("The type '{0}' must be static, public, and named 'PreApplicationStartCode'.", preAppStartType.FullName);
|
|
||||||
Assert.True(preAppStartType.IsSealed && preAppStartType.IsAbstract && preAppStartType.IsPublic && preAppStartType.Name == "PreApplicationStartCode", typeMessage);
|
|
||||||
|
|
||||||
string editorBrowsableMessage = String.Format("The only attribute on type '{0}' must be [EditorBrowsable(EditorBrowsableState.Never)].", preAppStartType.FullName);
|
|
||||||
object[] attrs = preAppStartType.GetCustomAttributes(typeof(EditorBrowsableAttribute), true);
|
|
||||||
Assert.True(attrs.Length == 1 && ((EditorBrowsableAttribute)attrs[0]).State == EditorBrowsableState.Never, editorBrowsableMessage);
|
|
||||||
|
|
||||||
string startMethodMessage = String.Format("The only public member on type '{0}' must be a method called Start().", preAppStartType.FullName);
|
|
||||||
MemberInfo[] publicMembers = preAppStartType.GetMembers(BindingFlags.Public | BindingFlags.Static);
|
|
||||||
Assert.True(publicMembers.Length == 1, startMethodMessage);
|
|
||||||
Assert.True(publicMembers[0].MemberType == MemberTypes.Method, startMethodMessage);
|
|
||||||
Assert.True(publicMembers[0].Name == "Start", startMethodMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Preserves the current <see cref="SynchronizationContext"/>. Use this attribute on
|
|
||||||
/// tests which modify the current <see cref="SynchronizationContext"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class PreserveSyncContextAttribute : Xunit.BeforeAfterTestAttribute
|
|
||||||
{
|
|
||||||
private SynchronizationContext _syncContext;
|
|
||||||
|
|
||||||
public override void Before(System.Reflection.MethodInfo methodUnderTest)
|
|
||||||
{
|
|
||||||
_syncContext = SynchronizationContext.Current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void After(System.Reflection.MethodInfo methodUnderTest)
|
|
||||||
{
|
|
||||||
SynchronizationContext.SetSynchronizationContext(_syncContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Security.Principal;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public class RestoreThreadPrincipalAttribute : Xunit.BeforeAfterTestAttribute
|
|
||||||
{
|
|
||||||
private IPrincipal _originalPrincipal;
|
|
||||||
|
|
||||||
public override void Before(MethodInfo methodUnderTest)
|
|
||||||
{
|
|
||||||
_originalPrincipal = Thread.CurrentPrincipal;
|
|
||||||
|
|
||||||
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.NoPrincipal);
|
|
||||||
|
|
||||||
Thread.CurrentPrincipal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void After(MethodInfo methodUnderTest)
|
|
||||||
{
|
|
||||||
Thread.CurrentPrincipal = _originalPrincipal;
|
|
||||||
|
|
||||||
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.UnauthenticatedPrincipal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Text;
|
|
||||||
using Xunit.Sdk;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
// An early copy of the new string assert exception from xUnit.net 2.0 (temporarily, until it RTMs)
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
internal class StringEqualException : AssertException
|
|
||||||
{
|
|
||||||
private static Dictionary<char, string> _encodings = new Dictionary<char, string> { { '\r', "\\r" }, { '\n', "\\n" }, { '\t', "\\t" }, { '\0', "\\0" } };
|
|
||||||
private string _message;
|
|
||||||
|
|
||||||
public StringEqualException(string expected, string actual, int expectedIndex, int actualIndex)
|
|
||||||
: base("Assert.Equal() failure")
|
|
||||||
{
|
|
||||||
Actual = actual;
|
|
||||||
ActualIndex = actualIndex;
|
|
||||||
Expected = expected;
|
|
||||||
ExpectedIndex = expectedIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Actual { get; private set; }
|
|
||||||
|
|
||||||
public int ActualIndex { get; private set; }
|
|
||||||
|
|
||||||
public string Expected { get; private set; }
|
|
||||||
|
|
||||||
public int ExpectedIndex { get; private set; }
|
|
||||||
|
|
||||||
public override string Message
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_message == null)
|
|
||||||
_message = CreateMessage();
|
|
||||||
|
|
||||||
return _message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string CreateMessage()
|
|
||||||
{
|
|
||||||
Tuple<string, string> printedExpected = ShortenAndEncode(Expected, ExpectedIndex, '↓');
|
|
||||||
Tuple<string, string> printedActual = ShortenAndEncode(Actual, ActualIndex, '↑');
|
|
||||||
|
|
||||||
return String.Format(
|
|
||||||
CultureInfo.CurrentCulture,
|
|
||||||
"{1}{0} {2}{0}Expected: {3}{0}Actual: {4}{0} {5}",
|
|
||||||
Environment.NewLine,
|
|
||||||
base.Message,
|
|
||||||
printedExpected.Item2,
|
|
||||||
printedExpected.Item1,
|
|
||||||
printedActual.Item1,
|
|
||||||
printedActual.Item2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Tuple<string, string> ShortenAndEncode(string value, int position, char pointer)
|
|
||||||
{
|
|
||||||
int start = Math.Max(position - 20, 0);
|
|
||||||
int end = Math.Min(position + 41, value.Length);
|
|
||||||
StringBuilder printedValue = new StringBuilder(100);
|
|
||||||
StringBuilder printedPointer = new StringBuilder(100);
|
|
||||||
|
|
||||||
if (start > 0)
|
|
||||||
{
|
|
||||||
printedValue.Append("···");
|
|
||||||
printedPointer.Append(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int idx = start; idx < end; ++idx)
|
|
||||||
{
|
|
||||||
char c = value[idx];
|
|
||||||
string encoding;
|
|
||||||
int paddingLength = 1;
|
|
||||||
|
|
||||||
if (_encodings.TryGetValue(c, out encoding))
|
|
||||||
{
|
|
||||||
printedValue.Append(encoding);
|
|
||||||
paddingLength = encoding.Length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printedValue.Append(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idx < position)
|
|
||||||
{
|
|
||||||
printedPointer.Append(' ', paddingLength);
|
|
||||||
}
|
|
||||||
else if (idx == position)
|
|
||||||
{
|
|
||||||
printedPointer.AppendFormat("{0} (pos {1})", pointer, position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end < value.Length)
|
|
||||||
{
|
|
||||||
printedValue.Append("···");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Tuple<string, string>(printedValue.ToString(), printedPointer.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool ExcludeStackFrame(string stackFrame)
|
|
||||||
{
|
|
||||||
return base.ExcludeStackFrame(stackFrame)
|
|
||||||
|| stackFrame.StartsWith("at Microsoft.TestCommon.Assert.", StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
// An early copy of the new string assert from xUnit.net 2.0 (temporarily, until it RTMs)
|
|
||||||
|
|
||||||
public partial class Assert
|
|
||||||
{
|
|
||||||
private const string NullDisplayValue = "(null)";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Verifies that two strings are equivalent.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="expected">The expected string value.</param>
|
|
||||||
/// <param name="actual">The actual string value.</param>
|
|
||||||
/// <param name="ignoreCase">If set to <c>true</c>, ignores cases differences. The invariant culture is used.</param>
|
|
||||||
/// <param name="ignoreLineEndingDifferences">If set to <c>true</c>, treats \r\n, \r, and \n as equivalent.</param>
|
|
||||||
/// <param name="ignoreWhiteSpaceDifferences">If set to <c>true</c>, treats spaces and tabs (in any non-zero quantity) as equivalent.</param>
|
|
||||||
/// <exception cref="Microsoft.TestCommon.Assert.StringEqualException">Thrown when the strings are not equivalent.</exception>
|
|
||||||
public static void Equal(string expected, string actual, bool ignoreCase = false, bool ignoreLineEndingDifferences = false, bool ignoreWhiteSpaceDifferences = false)
|
|
||||||
{
|
|
||||||
// Start out assuming the one of the values is null
|
|
||||||
int expectedIndex = -1;
|
|
||||||
int actualIndex = -1;
|
|
||||||
int expectedLength = 0;
|
|
||||||
int actualLength = 0;
|
|
||||||
|
|
||||||
if (expected == null)
|
|
||||||
{
|
|
||||||
if (actual == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
expected = NullDisplayValue;
|
|
||||||
}
|
|
||||||
else if (actual == null)
|
|
||||||
{
|
|
||||||
actual = NullDisplayValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Walk the string, keeping separate indices since we can skip variable amounts of
|
|
||||||
// data based on ignoreLineEndingDifferences and ignoreWhiteSpaceDifferences.
|
|
||||||
expectedIndex = 0;
|
|
||||||
actualIndex = 0;
|
|
||||||
expectedLength = expected.Length;
|
|
||||||
actualLength = actual.Length;
|
|
||||||
|
|
||||||
while (expectedIndex < expectedLength && actualIndex < actualLength)
|
|
||||||
{
|
|
||||||
char expectedChar = expected[expectedIndex];
|
|
||||||
char actualChar = actual[actualIndex];
|
|
||||||
|
|
||||||
if (ignoreLineEndingDifferences && IsLineEnding(expectedChar) && IsLineEnding(actualChar))
|
|
||||||
{
|
|
||||||
expectedIndex = SkipLineEnding(expected, expectedIndex);
|
|
||||||
actualIndex = SkipLineEnding(actual, actualIndex);
|
|
||||||
}
|
|
||||||
else if (ignoreWhiteSpaceDifferences && IsWhiteSpace(expectedChar) && IsWhiteSpace(actualChar))
|
|
||||||
{
|
|
||||||
expectedIndex = SkipWhitespace(expected, expectedIndex);
|
|
||||||
actualIndex = SkipWhitespace(actual, actualIndex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ignoreCase)
|
|
||||||
{
|
|
||||||
expectedChar = Char.ToUpperInvariant(expectedChar);
|
|
||||||
actualChar = Char.ToUpperInvariant(actualChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expectedChar != actualChar)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedIndex++;
|
|
||||||
actualIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expectedIndex < expectedLength || actualIndex < actualLength)
|
|
||||||
{
|
|
||||||
throw new StringEqualException(expected, actual, expectedIndex, actualIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsLineEnding(char c)
|
|
||||||
{
|
|
||||||
return c == '\r' || c == '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsWhiteSpace(char c)
|
|
||||||
{
|
|
||||||
return c == ' ' || c == '\t';
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int SkipLineEnding(string value, int index)
|
|
||||||
{
|
|
||||||
if (value[index] == '\r')
|
|
||||||
{
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
if (index < value.Length && value[index] == '\n')
|
|
||||||
{
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int SkipWhitespace(string value, int index)
|
|
||||||
{
|
|
||||||
while (index < value.Length)
|
|
||||||
{
|
|
||||||
switch (value[index])
|
|
||||||
{
|
|
||||||
case ' ':
|
|
||||||
case '\t':
|
|
||||||
index++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.TestCommon;
|
|
||||||
|
|
||||||
// No namespace so that these extensions are available for all test classes
|
|
||||||
|
|
||||||
public static class TaskExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Waits until the given task finishes executing and completes in any of the 3 states.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="task">A task</param>
|
|
||||||
public static void WaitUntilCompleted(this Task task)
|
|
||||||
{
|
|
||||||
if (task == null) throw new ArgumentNullException("task");
|
|
||||||
task.ContinueWith(prev =>
|
|
||||||
{
|
|
||||||
if (prev.IsFaulted)
|
|
||||||
{
|
|
||||||
// Observe the exception in the faulted case to avoid an unobserved exception leaking and
|
|
||||||
// killing the thread finalizer.
|
|
||||||
var e = prev.Exception;
|
|
||||||
}
|
|
||||||
}, TaskContinuationOptions.ExecuteSynchronously).Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RethrowFaultedTaskException(this Task task)
|
|
||||||
{
|
|
||||||
task.WaitUntilCompleted();
|
|
||||||
Assert.Equal(TaskStatus.Faulted, task.Status);
|
|
||||||
throw task.Exception.GetBaseException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.TestCommon;
|
|
||||||
|
|
||||||
namespace System.Web.TestUtil
|
|
||||||
{
|
|
||||||
public static class UnitTestHelper
|
|
||||||
{
|
|
||||||
public static bool EnglishBuildAndOS
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
bool englishBuild = String.Equals(CultureInfo.CurrentCulture.TwoLetterISOLanguageName, "en",
|
|
||||||
StringComparison.OrdinalIgnoreCase);
|
|
||||||
bool englishOS = String.Equals(CultureInfo.CurrentCulture.TwoLetterISOLanguageName, "en",
|
|
||||||
StringComparison.OrdinalIgnoreCase);
|
|
||||||
return englishBuild && englishOS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AssertEqualsIgnoreWhitespace(string expected, string actual)
|
|
||||||
{
|
|
||||||
expected = new String(expected.Where(c => !Char.IsWhiteSpace(c)).ToArray());
|
|
||||||
actual = new String(actual.Where(c => !Char.IsWhiteSpace(c)).ToArray());
|
|
||||||
|
|
||||||
Assert.Equal(expected, actual, StringComparer.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Helper class for generating test data for XUnit's <see cref="Xunit.Extensions.TheoryAttribute"/>-based tests.
|
|
||||||
/// Should be used in combination with <see cref="Xunit.Extensions.PropertyDataAttribute"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TParam">First parameter type</typeparam>
|
|
||||||
public class TheoryDataSet<TParam> : TheoryDataSet
|
|
||||||
{
|
|
||||||
public void Add(TParam p)
|
|
||||||
{
|
|
||||||
AddItem(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper class for generating test data for XUnit's <see cref="Xunit.Extensions.TheoryAttribute"/>-based tests.
|
|
||||||
/// Should be used in combination with <see cref="Xunit.Extensions.PropertyDataAttribute"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TParam1">First parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam2">Second parameter type</typeparam>
|
|
||||||
public class TheoryDataSet<TParam1, TParam2> : TheoryDataSet
|
|
||||||
{
|
|
||||||
public void Add(TParam1 p1, TParam2 p2)
|
|
||||||
{
|
|
||||||
AddItem(p1, p2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper class for generating test data for XUnit's <see cref="Xunit.Extensions.TheoryAttribute"/>-based tests.
|
|
||||||
/// Should be used in combination with <see cref="Xunit.Extensions.PropertyDataAttribute"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TParam1">First parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam2">Second parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam3">Third parameter type</typeparam>
|
|
||||||
public class TheoryDataSet<TParam1, TParam2, TParam3> : TheoryDataSet
|
|
||||||
{
|
|
||||||
public void Add(TParam1 p1, TParam2 p2, TParam3 p3)
|
|
||||||
{
|
|
||||||
AddItem(p1, p2, p3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper class for generating test data for XUnit's <see cref="Xunit.Extensions.TheoryAttribute"/>-based tests.
|
|
||||||
/// Should be used in combination with <see cref="Xunit.Extensions.PropertyDataAttribute"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TParam1">First parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam2">Second parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam3">Third parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam4">Fourth parameter type</typeparam>
|
|
||||||
public class TheoryDataSet<TParam1, TParam2, TParam3, TParam4> : TheoryDataSet
|
|
||||||
{
|
|
||||||
public void Add(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4)
|
|
||||||
{
|
|
||||||
AddItem(p1, p2, p3, p4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper class for generating test data for XUnit's <see cref="Xunit.Extensions.TheoryAttribute"/>-based tests.
|
|
||||||
/// Should be used in combination with <see cref="Xunit.Extensions.PropertyDataAttribute"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TParam1">First parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam2">Second parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam3">Third parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam4">Fourth parameter type</typeparam>
|
|
||||||
/// <typeparam name="TParam5">Fifth parameter type</typeparam>
|
|
||||||
public class TheoryDataSet<TParam1, TParam2, TParam3, TParam4, TParam5> : TheoryDataSet
|
|
||||||
{
|
|
||||||
public void Add(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TParam5 p5)
|
|
||||||
{
|
|
||||||
AddItem(p1, p2, p3, p4, p5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Base class for <c>TheoryDataSet</c> classes.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class TheoryDataSet : IEnumerable<object[]>
|
|
||||||
{
|
|
||||||
private readonly List<object[]> data = new List<object[]>();
|
|
||||||
|
|
||||||
protected void AddItem(params object[] values)
|
|
||||||
{
|
|
||||||
data.Add(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<object[]> GetEnumerator()
|
|
||||||
{
|
|
||||||
return data.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return GetEnumerator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This is an implementation of SynchronizationContext that not only queues things on the thread pool for
|
|
||||||
/// later work, but also ensures that it sets itself back as the synchronization context (something that the
|
|
||||||
/// default implementatation of SynchronizationContext does not do).
|
|
||||||
/// </summary>
|
|
||||||
public class ThreadPoolSyncContext : SynchronizationContext
|
|
||||||
{
|
|
||||||
public override void Post(SendOrPostCallback d, object state)
|
|
||||||
{
|
|
||||||
ThreadPool.QueueUserWorkItem(_ =>
|
|
||||||
{
|
|
||||||
SynchronizationContext oldContext = SynchronizationContext.Current;
|
|
||||||
SynchronizationContext.SetSynchronizationContext(this);
|
|
||||||
d.Invoke(state);
|
|
||||||
SynchronizationContext.SetSynchronizationContext(oldContext);
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Send(SendOrPostCallback d, object state)
|
|
||||||
{
|
|
||||||
SynchronizationContext oldContext = SynchronizationContext.Current;
|
|
||||||
SynchronizationContext.SetSynchronizationContext(this);
|
|
||||||
d.Invoke(state);
|
|
||||||
SynchronizationContext.SetSynchronizationContext(oldContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
|
||||||
public class TraitAttribute : Xunit.TraitAttribute
|
|
||||||
{
|
|
||||||
public TraitAttribute(string name, string value)
|
|
||||||
: base(name, value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Microsoft.TestCommon
|
|
||||||
{
|
|
||||||
public static class VersionTestHelper
|
|
||||||
{
|
|
||||||
// returns a version for an assembly by using a type from the assembly
|
|
||||||
// also verifies that type wasn't moved to another assembly.
|
|
||||||
public static Version GetVersionFromAssembly(string assemblyName, Type typeFromAssembly)
|
|
||||||
{
|
|
||||||
Assembly assembly = typeFromAssembly.Assembly;
|
|
||||||
|
|
||||||
Assert.Equal(assemblyName, assembly.GetName().Name);
|
|
||||||
return assembly.GetName().Version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Web.UI;
|
|
||||||
|
|
||||||
namespace System.Web.WebPages.TestUtils
|
|
||||||
{
|
|
||||||
public static class WebUtils
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Creates an instance of HttpRuntime and assigns it (using magic) to the singleton instance of HttpRuntime.
|
|
||||||
/// Ensure that the returned value is disposed at the end of the test.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Returns an IDisposable that restores the original HttpRuntime.</returns>
|
|
||||||
public static IDisposable CreateHttpRuntime(string appVPath, string appPath = null)
|
|
||||||
{
|
|
||||||
var runtime = new HttpRuntime();
|
|
||||||
var appDomainAppVPathField = typeof(HttpRuntime).GetField("_appDomainAppVPath", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
|
|
||||||
appDomainAppVPathField.SetValue(runtime, CreateVirtualPath(appVPath));
|
|
||||||
|
|
||||||
if (appPath != null)
|
|
||||||
{
|
|
||||||
var appDomainAppPathField = typeof(HttpRuntime).GetField("_appDomainAppPath", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
|
|
||||||
appDomainAppPathField.SetValue(runtime, Path.GetFullPath(appPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
GetTheRuntime().SetValue(null, runtime);
|
|
||||||
var appDomainIdField = typeof(HttpRuntime).GetField("_appDomainId", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
||||||
appDomainIdField.SetValue(runtime, "test");
|
|
||||||
|
|
||||||
return new DisposableAction(RestoreHttpRuntime);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static FieldInfo GetTheRuntime()
|
|
||||||
{
|
|
||||||
return typeof(HttpRuntime).GetField("_theRuntime", BindingFlags.NonPublic | BindingFlags.Static);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void RestoreHttpRuntime()
|
|
||||||
{
|
|
||||||
GetTheRuntime().SetValue(null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static object CreateVirtualPath(string path)
|
|
||||||
{
|
|
||||||
var vPath = typeof(Page).Assembly.GetType("System.Web.VirtualPath");
|
|
||||||
var method = vPath.GetMethod("CreateNonRelativeTrailingSlash", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
|
||||||
return method.Invoke(null, new object[] { path });
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DisposableAction : IDisposable
|
|
||||||
{
|
|
||||||
private Action _action;
|
|
||||||
private bool _hasDisposed;
|
|
||||||
|
|
||||||
public DisposableAction(Action action)
|
|
||||||
{
|
|
||||||
if (action == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("action");
|
|
||||||
}
|
|
||||||
_action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
// If we were disposed by the finalizer it's because the user didn't use a "using" block, so don't do anything!
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
lock (this)
|
|
||||||
{
|
|
||||||
if (!_hasDisposed)
|
|
||||||
{
|
|
||||||
_hasDisposed = true;
|
|
||||||
_action();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue