Commit 5960059b authored by An Ionescu's avatar An Ionescu

Refactoring the testing infrastructure for better readability and less code duplication

parent 1d508c6d
using System.Collections;
using System.Collections.Generic;
namespace Anvoker.Collections.Maps
{
public interface IValueSets<T> : IReadOnlyValueSets<T>, ICollection<ICollection<T>>
{ }
public interface IReadOnlyValueSets<T> : IReadOnlyCollection<IReadOnlyCollection<T>>
{ }
}
......@@ -18,7 +18,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<OutputPath>..\..\bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
......@@ -48,7 +48,6 @@
<Compile Include="Interfaces\IReadOnlyBiMap.cs" />
<Compile Include="Interfaces\IReadOnlyMultiBiMap.cs" />
<Compile Include="Interfaces\IReadOnlyMultiMap.cs" />
<Compile Include="Interfaces\IValueSets.cs" />
<Compile Include="MultiBiMap.cs" />
<Compile Include="MultiMap.cs" />
<Compile Include="ValueSet.cs" />
......
......@@ -6,19 +6,15 @@ using System.Linq;
namespace Anvoker.Collections.Maps
{
public interface ISetPlus<T> : ISet<T>
{
bool Add(IEnumerable<T> item);
bool Remove(IEnumerable<T> item);
}
/// <summary>
/// Represents a set of values used in a collection.
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TVal"></typeparam>
/// <typeparam name="TKey">The type of the keys.
/// </typeparam>
/// <typeparam name="TVal">The type of the values.
/// </typeparam>
public class ValueSet<TKey, TVal> :
ISetPlus<TVal>,
ISet<TVal>,
IReadOnlyCollection<TVal>
{
#region Public Constructors
......@@ -61,6 +57,7 @@ namespace Anvoker.Collections.Maps
public bool IsReadOnly => false;
public TKey Key { get; }
public IMultiMap<TKey, TVal> Parent { get; }
public int Count => HashSet.Count;
......@@ -120,9 +117,6 @@ namespace Anvoker.Collections.Maps
bool ISet<TVal>.Add(TVal item)
=> Parent.AddValue(Key, item);
bool ISetPlus<TVal>.Add(IEnumerable<TVal> item)
=> Parent.AddValues(Key, item);
void ICollection<TVal>.Add(TVal item)
=> Parent.AddValue(Key, item);
......@@ -142,9 +136,6 @@ namespace Anvoker.Collections.Maps
bool ICollection<TVal>.Remove(TVal item)
=> Parent.RemoveValue(Key, item);
bool ISetPlus<TVal>.Remove(IEnumerable<TVal> item)
=> Parent.RemoveValues(Key, item);
void ISet<TVal>.SymmetricExceptWith(IEnumerable<TVal> other)
{
var common = HashSet.Intersect(other, HashSet.Comparer);
......
......@@ -220,8 +220,10 @@ namespace Anvoker.Collections.Tests.Common
var enumerator = second.GetEnumerator();
for (int i = 0; i < first.Length; i++, enumerator.MoveNext())
{
var union = new List<TValue>(first[i]);
union.Add(enumerator.Current);
var union = new List<TValue>(first[i])
{
enumerator.Current
};
values[i] = collectionConstructor(union);
}
......
......@@ -53,7 +53,9 @@ namespace Anvoker.Collections.Tests.Common
(x, y, ignoreEmpty) => x.GetKeysWithSubset(y, ignoreEmpty),
(x, y, ignoreEmpty) => x.GetKeysWithSuperset(y, ignoreEmpty),
(x, y, ignoreEmpty) => x.GetKeysWithEqualSet(y, ignoreEmpty),
#pragma warning disable RCS1163 // Unused parameter.
(x, y, ignoreEmpty) => x.GetKeysWithAny(y)
#pragma warning restore RCS1163 // Unused parameter.
};
private static readonly string[] SelectorNames = new string[]
......@@ -64,7 +66,9 @@ namespace Anvoker.Collections.Tests.Common
"Any"
};
#pragma warning disable RCS1158 // Static member in generic type should use a type parameter.
public static IEnumerable<TestCaseData> SelectorCases
#pragma warning restore RCS1158 // Static member in generic type should use a type parameter.
{
get
{
......
......@@ -20,7 +20,7 @@ namespace Anvoker.Collections.Tests.Common
/// <see cref="IReadOnlyDictionary{TKey, TValue}"/>.</typeparam>
/// <typeparam name="TValCol">Type of the nested collection used as the
/// value type in <see cref="IDictionary{TKey, TValue}"/>.</typeparam>
public class IReadOnlyDictionaryNestedBase<TKey, TVal, TIDict, TValCol> :
public class IRODictionaryNestedBase<TKey, TVal, TIDict, TValCol> :
MapTestDataConstructible<TKey, TVal, TIDict, TValCol>
where TIDict : IReadOnlyDictionary<TKey, TValCol>
where TValCol : IEnumerable<TVal>
......@@ -40,7 +40,7 @@ namespace Anvoker.Collections.Tests.Common
/// </summary>
/// <param name="args">A data class containing all of the necessary
/// arguments for initializing the tests.</param>
public IReadOnlyDictionaryNestedBase(
public IRODictionaryNestedBase(
MapTestDataConcrete<TKey, TVal, TIDict, TValCol> args)
{
d = args;
......
......@@ -9,17 +9,23 @@ namespace Anvoker.Collections.Tests.Common
: IMapTestDataConstructible
{
public static TestFixtureParameters
ConstructFixtureParams(
Func<TIDict> ctorImplementor,
Func<IEnumerable<TVal>, TValCol> ctorTValCol,
MakeFixtureParams(
Func<MapTestData<TKey, TVal>, TIDict> ctorImplementor,
Func<IEnumerable<TVal>, IEqualityComparer<TVal>, TValCol> ctorValCol,
MapTestData<TKey, TVal> data,
string testName)
string concreteTypeName)
{
TIDict pAppCtorImplementor()
=> ctorImplementor(data);
TValCol pAppCtorValCol(IEnumerable<TVal> x)
=> ctorValCol(x, data.ComparerValue);
var args = new MapTestDataConcrete<TKey, TVal, TIDict, TValCol>(
ctorImplementor, ctorTValCol, data);
pAppCtorImplementor, pAppCtorValCol, data);
var exposedParams = new ExposedTestFixtureParams()
{
TestName = testName,
TestName = $"{concreteTypeName} | {data.TestDataName}",
Arguments = new object[] { args },
Properties = new PropertyBag(),
RunState = RunState.Runnable,
......@@ -36,5 +42,6 @@ namespace Anvoker.Collections.Tests.Common
}
}
public interface IMapTestDataConstructible { }
public interface IMapTestDataConstructible
{ }
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using NUnit.Framework.Internal;
namespace Anvoker.Collections.Tests.Common
{
/// <summary>
/// Provides key, values and comparers appropriate for testing maps.
/// </summary>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <typeparam name="TVal">The type of the value.</typeparam>
public static class MapTestDataExtensionMethods
{
public static TestFixtureParameters Construct
<TKey, TVal, TIDict, TValCol>(
this MapTestData<TKey, TVal> data,
Func<TKey[], TVal[][], IEqualityComparer<TKey>, IEqualityComparer<TVal>, TIDict> collectionCtor,
Func<IEnumerable<TVal>, IEqualityComparer<TVal>, TValCol> valueCollectionCtor,
string concreteTypeName)
{
var keyType = typeof(TKey);
var valType = typeof(TVal);
string testName
= $"{concreteTypeName} | {data.TestDataName}";
return MapTestDataConstructible<TKey, TVal, TIDict, TValCol>
.ConstructFixtureParams(
() => collectionCtor(
data.KeysInitial,
data.ValuesInitial,
data.ComparerKey,
data.ComparerValue),
(IEnumerable<TVal> values) => valueCollectionCtor(
values,
data.ComparerValue),
data,
testName);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
namespace Anvoker.Collections.Tests.Common
{
public static class MapTestDataFixtureParametersConstructor
{
public static TestFixtureParameters Construct<TKey, TVal, TIDict, TValCol, TInterfaceTester>(
MapTestData<TKey, TVal> data,
Func<TKey[], TVal[][], IEqualityComparer<TKey>, IEqualityComparer<TVal>, TIDict> collectionCtor,
Func<IEnumerable<TVal>, IEqualityComparer<TVal>, TValCol> valueCollectionCtor)
where TInterfaceTester : MapTestDataConstructible<TKey, TVal, TIDict, TValCol>
{
var keyType = typeof(TKey);
var valType = typeof(TVal);
string testName
= $"{nameof(TIDict)} | {data.TestDataName}";
return MapTestDataConstructible<TKey, TVal, TIDict, TValCol>
.ConstructFixtureParams(
() => collectionCtor(
data.KeysInitial,
data.ValuesInitial,
data.ComparerKey,
data.ComparerValue),
(IEnumerable<TVal> values) => valueCollectionCtor(
values,
data.ComparerValue),
data,
testName);
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Common")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Common")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("beab10ef-bd0d-4144-9ad0-d3bd1c052246")]
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
......@@ -107,5 +107,20 @@
</Rules>
<AnalyzerSettings />
</Analyzer>
<Analyzer AnalyzerId="StyleCop.CSharp.LayoutRules">
<Rules>
<Rule Name="ElementMustNotBeOnSingleLine">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
<Rule Name="AllAccessorsMustBeMultiLineOrSingleLine">
<RuleSettings>
<BooleanProperty Name="Enabled">False</BooleanProperty>
</RuleSettings>
</Rule>
</Rules>
<AnalyzerSettings />
</Analyzer>
</Analyzers>
</StyleCopSettings>
\ No newline at end of file
......@@ -24,7 +24,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<OutputPath>..\..\..\bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
......@@ -51,10 +51,9 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="MapTestDataExtensionMethods.cs" />
<Compile Include="MapTestDataFixtureParametersConstructor.cs" />
<Compile Include="Tracing.cs" />
<Compile Include="MapTestDataConstructible.cs" />
<Compile Include="InterfaceTesters\IReadOnlyDictionaryNestedBase.cs" />
<Compile Include="InterfaceTesters\IRODictionaryNestedBase.cs" />
<Compile Include="InterfaceTesters\IMultiBiMapBase.cs" />
<Compile Include="MapTestDataConcrete.cs" />
<Compile Include="InterfaceTesters\IMultiMapBase.cs" />
......
......@@ -2,20 +2,20 @@
using Anvoker.Collections.Tests.Common;
using NUnit.Framework;
namespace Anvoker.Collections.Tests.Maps.IDictionaryNested
namespace Anvoker.Collections.Tests.Maps.ForwardingFixtures
{
[TestFixtureSource(
typeof(MultiBiMap.IDictionaryNested_FixtureSource),
nameof(MultiBiMap.IDictionaryNested_FixtureSource.GetFixtureArgs))]
typeof(MultiBiMap.FixtureSource_IDictionaryNested),
nameof(MultiBiMap.FixtureSource_IDictionaryNested.GetArgs))]
[TestFixtureSource(
typeof(MultiMap.IDictionaryNested_FixtureSource),
nameof(MultiMap.IDictionaryNested_FixtureSource.GetFixtureArgs))]
public class ForwardingFixture<TKey, TVal, TIDict, TValCol>
typeof(MultiMap.FixtureSource_IDictionaryNested),
nameof(MultiMap.FixtureSource_IDictionaryNested.GetArgs))]
public class IDictionaryNestedDerived<TKey, TVal, TIDict, TValCol>
: IDictionaryNestedBase<TKey, TVal, TIDict, TValCol>
where TIDict : IDictionary<TKey, TValCol>
where TValCol : IEnumerable<TVal>
{
public ForwardingFixture(
public IDictionaryNestedDerived(
MapTestDataConcrete<TKey, TVal, TIDict, TValCol> args) : base(args)
{ }
}
......
......@@ -6,8 +6,8 @@ using NUnit.Framework;
namespace Anvoker.Collections.Tests.Maps.IMultiBiMap
{
[TestFixtureSource(
typeof(MultiBiMap.IMultiBiMap_FixtureSource),
nameof(MultiBiMap.IMultiBiMap_FixtureSource.GetFixtureArgs))]
typeof(MultiBiMap.FixtureSource_IMultiBiMap),
nameof(MultiBiMap.FixtureSource_IMultiBiMap.GetArgs))]
public class ForwardingFixture_IMultiBiMap<TKey, TVal, TMultiBiMap, TValCol>
: IMultiBiMapBase<TKey, TVal, TMultiBiMap, TValCol>
where TMultiBiMap : IMultiBiMap<TKey, TVal>
......
......@@ -6,11 +6,11 @@ using NUnit.Framework;
namespace Anvoker.Collections.Tests.Maps.IMultiMap
{
[TestFixtureSource(
typeof(MultiBiMap.IMultiMap_FixtureSource),
nameof(MultiBiMap.IMultiMap_FixtureSource.GetFixtureArgs))]
typeof(MultiBiMap.FixtureSource_IMultiMap),
nameof(MultiBiMap.FixtureSource_IMultiMap.GetArgs))]
[TestFixtureSource(
typeof(MultiMap.IMultiMap_FixtureSource),
nameof(MultiMap.IMultiMap_FixtureSource.GetFixtureArgs))]
typeof(MultiMap.FixtureSource_IMultiMap),
nameof(MultiMap.FixtureSource_IMultiMap.GetArgs))]
public class ForwardingFixture<TKey, TVal, TMultiMap, TValCol>
: IMultiMapBase<TKey, TVal, TMultiMap, TValCol>
where TMultiMap : IMultiMap<TKey, TVal>
......
......@@ -5,13 +5,13 @@ using NUnit.Framework;
namespace Anvoker.Collections.Tests.Maps.IReadOnlyDictionaryNested
{
[TestFixtureSource(
typeof(MultiBiMap.IReadOnlyDictionaryNested_FixtureSource),
nameof(MultiBiMap.IReadOnlyDictionaryNested_FixtureSource.GetFixtureArgs))]
typeof(MultiBiMap.FixtureSource_IRODictionaryNested),
nameof(MultiBiMap.FixtureSource_IRODictionaryNested.GetArgs))]
[TestFixtureSource(
typeof(MultiMap.IReadOnlyDictionaryNested_FixtureSource),
nameof(MultiMap.IReadOnlyDictionaryNested_FixtureSource.GetFixtureArgs))]
typeof(MultiMap.FixtureSource_IRODictionaryNested),
nameof(MultiMap.FixtureSource_IRODictionaryNested.GetArgs))]
public class ForwardingFixture<TKey, TVal, TIDict, TValCol>
: IReadOnlyDictionaryNestedBase<TKey, TVal, TIDict, TValCol>
: IRODictionaryNestedBase<TKey, TVal, TIDict, TValCol>
where TIDict : IReadOnlyDictionary<TKey, TValCol>
where TValCol : IEnumerable<TVal>
{
......
......@@ -43,9 +43,9 @@ namespace Anvoker.Collections.Tests.Maps
comparerValue: null);
public static readonly
MapTestData<string, string> StringStringCaseSensitive
MapTestData<string, string> StringStringSensitive
= new MapTestData<string, string>(
testDataName: nameof(StringStringCaseSensitive),
testDataName: nameof(StringStringSensitive),
keysInitial: new string[] { "nyaa", "nyAA", "\"\"", string.Empty },
keysToAdd: new string[] { "meow", "meoW", "Meow" },
keysExcluded: new string[] { "NYAA", "NYaA", " " },
......@@ -72,9 +72,9 @@ namespace Anvoker.Collections.Tests.Maps
comparerValue: StringComparer.InvariantCulture);
public static readonly
MapTestData<string, string> StringStringCaseInsensitive
MapTestData<string, string> StringStringInsensitive
= new MapTestData<string, string>(
testDataName: nameof(StringStringCaseInsensitive),
testDataName: nameof(StringStringInsensitive),
keysInitial: new string[]
{
"nyaa1", "nyaa2", string.Empty, " "
......@@ -104,9 +104,9 @@ namespace Anvoker.Collections.Tests.Maps
comparerValue: StringComparer.InvariantCultureIgnoreCase);
public static readonly
MapTestData<List<int>, Type> ListType
MapTestData<List<int>, Type> ListIntType
= new MapTestData<List<int>, Type>(
testDataName: nameof(ListType),
testDataName: nameof(ListIntType),
keysInitial: new List<int>[]
{
new List<int>(),
......
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Anvoker.Collections.Tests.Common;
using System.Reflection;
using System.Text;
using Anvoker.Collections.Tests.Common;
using NUnit.Framework;
namespace Anvoker.Collections.Tests.Maps
......@@ -11,15 +11,15 @@ namespace Anvoker.Collections.Tests.Maps
[TestFixture]
public class MapTestDataSourceValidator
{
private readonly static MethodInfo validateMethodUnbound =
private static readonly MethodInfo validateMethodUnbound =
typeof(MapTestDataSourceValidator).GetMethod(
nameof(Validate),
BindingFlags.NonPublic | BindingFlags.Static);
private readonly static Type genericMap
private static readonly Type genericMap
= typeof(MapTestData<,>).GetGenericTypeDefinition();
private readonly static FieldInfo[] fields
private static readonly FieldInfo[] fields
= typeof(MapTestDataSource).GetFields(
BindingFlags.Static | BindingFlags.Public);
......
using System;
using System.Collections.Generic;
using Anvoker.Collections.Maps;
using Anvoker.Collections.Tests.Common;
using NUnit.Framework.Interfaces;
using static Anvoker.Collections.Tests.Maps.MapTestDataSource;
using static Anvoker.Collections.Tests.Maps.MultiBiMap.MultiBiMapHelpers;
namespace Anvoker.Collections.Tests.Maps.MultiBiMap
{
/// <summary>
/// Provides test data for a
/// <see cref="IDictionaryNestedBase{TKey, TVal, TMultiMap, TValCol}"/> test
/// fixture.
/// </summary>
public static class FixtureSource_IDictionaryNested
{
public static ITestFixtureData[] GetArgs
{ get; } = new ITestFixtureData[]
{
IDictionaryNestedBase<int, decimal,
IMultiBiMap<int, decimal>,
ICollection<decimal>>
.MakeFixtureParams(Ctor, CtorValCol, IntDecimal, Name),
IDictionaryNestedBase<string, string,
IMultiBiMap<string, string>,
ICollection<string>>
.MakeFixtureParams(Ctor, CtorValCol, StringStringInsensitive, Name),
IDictionaryNestedBase<string, string,
IMultiBiMap<string, string>,
ICollection<string>>
.MakeFixtureParams(Ctor, CtorValCol, StringStringSensitive, Name),
IDictionaryNestedBase<List<int>, Type,
IMultiBiMap<List<int>, Type>,
ICollection<Type>>
.MakeFixtureParams(Ctor, CtorValCol, ListIntType, Name)
};
}
}
using System;
using System.Collections.Generic;
using Anvoker.Collections.Maps;
using Anvoker.Collections.Tests.Common;
using NUnit.Framework.Interfaces;
using static Anvoker.Collections.Tests.Maps.MapTestDataSource;
using static Anvoker.Collections.Tests.Maps.MultiBiMap.MultiBiMapHelpers;
namespace Anvoker.Collections.Tests.Maps.MultiBiMap
{
/// <summary>
/// Provides test data for a
/// <see cref="IMultiBiMapBase{TKey, TVal, TMultiMap, TValCol}"/> test
/// fixture.
/// </summary>
public static class FixtureSource_IMultiBiMap
{
public static ITestFixtureData[] GetArgs
{ get; } = new ITestFixtureData[]
{
IMultiBiMapBase<int, decimal,
IMultiBiMap<int, decimal>,
ICollection<decimal>>
.MakeFixtureParams(Ctor, CtorValCol, IntDecimal, Name),
IMultiBiMapBase<string, string,
IMultiBiMap<string, string>,
ICollection<string>>
.MakeFixtureParams(Ctor, CtorValCol, StringStringInsensitive, Name),
IMultiBiMapBase<string, string,
IMultiBiMap<string, string>,
ICollection<string>>
.MakeFixtureParams(Ctor, CtorValCol, StringStringSensitive, Name),
IMultiBiMapBase<List<int>, Type,
IMultiBiMap<List<int>, Type>,
ICollection<Type>>
.MakeFixtureParams(Ctor, CtorValCol, ListIntType, Name)
};
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using Anvoker.Collections.Maps;
using Anvoker.Collections.Tests.Common;
using NUnit.Framework.Interfaces;
using static Anvoker.Collections.Tests.Maps.MapTestDataSource;
using static Anvoker.Collections.Tests.Maps.MultiBiMap.MultiBiMapHelpers;
namespace Anvoker.Collections.Tests.Maps.MultiBiMap
{
/// <summary>
/// Provides test data for a
/// <see cref="IMultiMapBase{TKey, TVal, TMultiMap, TValCol}"/> test
/// fixture.
/// </summary>
public static class FixtureSource_IMultiMap
{
public static ITestFixtureData[] GetArgs
{ get; } = new ITestFixtureData[]
{
IMultiMapBase<int, decimal,
IMultiBiMap<int, decimal>,
ICollection<decimal>>
.MakeFixtureParams(Ctor, CtorValCol, IntDecimal, Name),
IMultiMapBase<string, string,
IMultiBiMap<string, string>,
ICollection<string>>
.MakeFixtureParams(Ctor, CtorValCol, StringStringInsensitive, Name),