Commit 9c6a18ca authored by An Ionescu's avatar An Ionescu

Removing NUnit.FixtureDependent from the source code; going to use a nuget dependency instead.

parent 83538cdb
......@@ -17,12 +17,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Common", "src\Tests\Common\Tests.Common.csproj", "{BEAB10EF-BD0D-4144-9AD0-D3BD1C052246}"
ProjectSection(ProjectDependencies) = postProject
{AD1A36AB-C528-4507-9B45-F75F1806C7B1} = {AD1A36AB-C528-4507-9B45-F75F1806C7B1}
{CA98F1BE-E77B-4B55-9B87-4F4F6F7BF412} = {CA98F1BE-E77B-4B55-9B87-4F4F6F7BF412}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NUnitFixtureDependent", "src\NUnitFixtureDependent\NUnitFixtureDependent.csproj", "{AD1A36AB-C528-4507-9B45-F75F1806C7B1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -41,10 +38,6 @@ Global
{BEAB10EF-BD0D-4144-9AD0-D3BD1C052246}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEAB10EF-BD0D-4144-9AD0-D3BD1C052246}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BEAB10EF-BD0D-4144-9AD0-D3BD1C052246}.Release|Any CPU.Build.0 = Release|Any CPU
{AD1A36AB-C528-4507-9B45-F75F1806C7B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD1A36AB-C528-4507-9B45-F75F1806C7B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD1A36AB-C528-4507-9B45-F75F1806C7B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD1A36AB-C528-4507-9B45-F75F1806C7B1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
</configuration>
// ***********************************************************************
// Copyright (c) 2008 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using System.Collections;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal.Builders;
namespace NUnit.Framework
{
/// <summary>
/// Marks a test to use a combinatorial join of any argument
/// data provided.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class CombinatorialDependentAttribute : CombiningStrategyDependentAttribute
{
/// <summary>
/// Default constructor
/// </summary>
public CombinatorialDependentAttribute()
: base(new CombinatorialStrategy(),
new ParameterDependentDataSourceProvider()) { }
}
}
// ***********************************************************************
// Copyright (c) 2014-2015 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using System.Collections;
using System.Collections.Generic;
#if NETCF
using System.Linq;
#endif
namespace NUnit.Framework
{
using Interfaces;
using Internal;
using Internal.Builders;
/// <summary>
/// Marks a test to use a particular CombiningStrategy to join
/// any parameter data provided.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public abstract class CombiningStrategyDependentAttribute : NUnitAttribute, ITestBuilder, IApplyToTest
{
private NUnitTestCaseBuilder _builder = new NUnitTestCaseBuilder();
private ICombiningStrategy _strategy;
private IParameterDependentDataProvider _dataProvider;
/// <summary>
/// Construct a CombiningStrategyAttribute incorporating an
/// ICombiningStrategy and an IParamterDataProvider.
/// </summary>
/// <param name="strategy">Combining strategy to be used in combining data</param>
/// <param name="provider">An IParameterDataProvider to supply data</param>
protected CombiningStrategyDependentAttribute(ICombiningStrategy strategy, IParameterDependentDataProvider provider)
{
_strategy = strategy;
_dataProvider = provider;
}
/// <summary>
/// Construct a CombiningStrategyAttribute incorporating an object
/// that implements ICombiningStrategy and an IParameterDataProvider.
/// This constructor is provided for CLS compliance.
/// </summary>
/// <param name="strategy">Combining strategy to be used in combining data</param>
/// <param name="provider">An IParameterDataProvider to supply data</param>
protected CombiningStrategyDependentAttribute(object strategy, object provider)
: this((ICombiningStrategy)strategy, (IParameterDependentDataProvider)provider)
{
}
#region ITestBuilder Members
/// <summary>
/// Construct one or more TestMethods from a given MethodInfo,
/// using available parameter data.
/// </summary>
/// <param name="method">The MethodInfo for which tests are to be constructed.</param>
/// <param name="suite">The suite to which the tests will be added.</param>
/// <returns>One or more TestMethods</returns>
public IEnumerable<TestMethod> BuildFrom(IMethodInfo method, Test suite)
{
List<TestMethod> tests = new List<TestMethod>();
#if NETCF
if (method.ContainsGenericParameters)
{
var genericParams = method.GetGenericArguments();
var numGenericParams = genericParams.Length;
var o = new object();
var tryArgs = Enumerable.Repeat(o, numGenericParams).ToArray();
IMethodInfo mi;
try
{
// This fails if the generic method has constraints
// that are not met by object.
mi = method.MakeGenericMethodEx(tryArgs);
if (mi == null)
return tests;
}
catch
{
return tests;
}
var par = mi.GetParameters();
if (par.Length == 0)
return tests;
var sourceData = par.Select(p => _dataProvider.GetDataFor(p, suite)).ToArray();
foreach (var parms in _strategy.GetTestCases(sourceData))
{
mi = method.MakeGenericMethodEx(parms.Arguments);
if (mi == null)
{
var tm = new TestMethod(method, suite);
tm.RunState = RunState.NotRunnable;
tm.Properties.Set(PropertyNames.SkipReason, "Incompatible arguments");
tests.Add(tm);
}
else
tests.Add(_builder.BuildTestMethod(mi, suite, (TestCaseParameters)parms));
}
return tests;
}
#endif
IParameterInfo[] parameters = method.GetParameters();
if (parameters.Length > 0)
{
IEnumerable[] sources = new IEnumerable[parameters.Length];
try
{
for (int i = 0; i < parameters.Length; i++)
sources[i] = _dataProvider.GetDataFor(parameters[i], suite);
}
catch (InvalidDataSourceException ex)
{
var parms = new TestCaseParameters();
parms.RunState = RunState.NotRunnable;
parms.Properties.Set(PropertyNames.SkipReason, ex.Message);
tests.Add(_builder.BuildTestMethod(method, suite, parms));
return tests;
}
foreach (var parms in _strategy.GetTestCases(sources))
tests.Add(_builder.BuildTestMethod(method, suite, (TestCaseParameters)parms));
}
return tests;
}
#endregion
#region IApplyToTest Members
/// <summary>
/// Modify the test by adding the name of the combining strategy
/// to the properties.
/// </summary>
/// <param name="test">The test to modify</param>
public void ApplyToTest(Test test)
{
var joinType = _strategy.GetType().Name;
if (joinType.EndsWith("Strategy"))
joinType = joinType.Substring(0, joinType.Length - 8);
test.Properties.Set(PropertyNames.JoinType, joinType);
}
#endregion
}
}
// ***********************************************************************
// Copyright (c) 2008 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using System.Collections;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal.Builders;
namespace NUnit.Framework
{
/// <summary>
/// Marks a test to use a pairwise join of any argument
/// data provided. Arguments will be combined in such a
/// way that all possible pairs of arguments are used.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class PairwiseDependentAttribute : CombiningStrategyDependentAttribute
{
/// <summary>
/// Default constructor
/// </summary>
public PairwiseDependentAttribute()
: base(new PairwiseStrategy(),
new ParameterDependentDataSourceProvider()) { }
}
}
// ***********************************************************************
// Copyright (c) 2008 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using System.Collections;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal.Builders;
namespace NUnit.Framework
{
/// <summary>
/// Marks a test to use a Sequential join of any argument
/// data provided. Arguments will be combined into test cases,
/// taking the next value of each argument until all are used.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class SequentialDependentAttribute : CombiningStrategyDependentAttribute
{
/// <summary>
/// Default constructor
/// </summary>
public SequentialDependentAttribute()
: base(new SequentialDependentStrategy(true),
new ParameterDependentDataSourceProvider()) { }
public SequentialDependentAttribute(bool stopAtShortestSource)
: base(new SequentialDependentStrategy(stopAtShortestSource),
new ParameterDependentDataSourceProvider())
{ }
}
}
// ***********************************************************************
// Copyright (c) 2008-2015 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using NUnit.Compatibility;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using static NUnitFixtureDependent.ReflectionHelper;
namespace NUnit.Framework
{
/// <summary>
/// Indicates a source that will provide data for one parameter of a test
/// method that is dependent on the arguments used to construct the Test
/// Fixture. This ONLY works with a Test Fixture that uses arguments in
/// its construction. So it works only when the Test Fixture has an
/// attribute like <see cref="TestFixtureSourceAttribute"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = false)]
public class ValueDependentSourceAttribute : Attribute, IParameterDependentDataSource
{
private const BindingFlags ALL_BINDINGS = BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Static
| BindingFlags.Instance | BindingFlags.FlattenHierarchy;
#region Constructors
/// <summary>
/// Construct with a type and name. The type is used to locate an
/// argument in the argument list of the Test Fixture constructor.
/// The argument must either be of that type or inherit from that type.
/// After the argument is located, <paramref name="sourceName"/> is used
/// to retrieve data from it, by accessing a method, property or field
/// by that name, that belongs to the located argument.
/// </summary>
/// <param name="sourceType">The Type of the fixture constructor
/// argument that will provide data.</param>
/// <param name="sourceName">The name of a method, property or field
/// belonging to <paramref name="sourceType"/> that will provide
/// data.</param>
public ValueDependentSourceAttribute(
Type sourceType,
string sourceName)
{
SourceType = sourceType
?? throw new ArgumentNullException(nameof(sourceType));
SourceName = sourceName
?? throw new ArgumentNullException(nameof(sourceName));
if (sourceType.GetMember(sourceName, ALL_BINDINGS) == null)
{
throw new InvalidDataSourceException(
$"The {nameof(sourceName)} specified on a " +
$"{nameof(ValueDependentSourceAttribute)} must refer to a field, property or " +
$"method that belongs to {nameof(sourceType)}.");
}
}
#endregion
#region Properties
/// <summary>
/// The name of the method, property or field, belonging to
/// <see cref="SourceType"/>, to be used as a source.
/// </summary>
public string SourceName { get; }
/// <summary>
/// The type of the Test Fixture argument to locate and use as a source.
/// </summary>
public Type SourceType { get; }
#endregion
#region IParameterDependentDataSource Members
/// <summary>
/// Gets an enumeration of data items for use as arguments
/// for a test method parameter.
/// </summary>
/// <param name="parameter">The parameter for which data is needed</param>
/// <returns>
/// An enumeration containing individual data items
/// </returns>
public IEnumerable GetData(IParameterInfo parameter, Test suite)
{
return GetDataSource(parameter, suite);
}
#endregion
#region Helper Methods
private IEnumerable GetDataSource(IParameterInfo parameter, Test suite)
{
var fixtureDataObject = LocateArgumentByType(suite.Arguments, SourceType);
if (fixtureDataObject == null)
{
throw new InvalidDataSourceException(
$"The {nameof(SourceType)} specified on a " +
$"{nameof(ValueDependentSourceAttribute)} must refer to an argument of that " +
"type that exists in the argument list of the containing Test Fixture.");
}
var argumentType = fixtureDataObject.GetType();
MemberInfo[] members = argumentType.GetMember(SourceName, ALL_BINDINGS);
var dataSource = GetDataSourceValue(parameter, members, fixtureDataObject);
if (dataSource == null)
{
throw new InvalidDataSourceException(
$"Could not retrieve a value from {argumentType}.{SourceName}. " +
$"{SourceName} is inaccessible via reflection or does not exist.");
}
return dataSource;
}
private static object LocateArgumentByType(object[] arguments, Type type)
{
foreach (var argument in arguments)
{
var argumentType = argument.GetType();
if (type == argumentType || argumentType.IsSubclassOf(type))
{
return argument;
}
else
{
foreach (var i in argumentType.GetInterfaces())
{
if (i.GetGenericTypeDefinition() == type)
{
return argument;
}
}
}
}
return null;
}
private static IEnumerable GetDataSourceValue(
IParameterInfo parameter,
MemberInfo[] members,
object fixtureDataObject)
{
if (members.Length <= 0)
{
return null;
}
MemberInfo member = null;
// If we have more than one member of the same name, this most
// likely means that a member is hiding a member on a different
// level of the inheritance hierarchy with the "new" keyword.
// In this case we need to compare the type of the member and the
// type of the parameter to figure out which member is the correct
// one.
if (members.Length > 1)
{
foreach (var m in members)
{
var memberType = m.GetMemberUnderlyingType();
var elementType = GetCollectionElementType(memberType);
if (parameter.ParameterType.IsAssignableFrom(elementType))
{
member = m;
}
}
}
else
{
member = members[0];
}
var value = member.GetValue(fixtureDataObject);
return (value != null) ? (IEnumerable)value : null;
}
#endregion
}
}
\ No newline at end of file
// ***********************************************************************