Browse Source

unit tests: new generic argument checking contract, functional helpers now globally available

Signed-off-by: Christoph Ruegg <git@cdrnet.ch>
pull/36/head
Christoph Ruegg 17 years ago
parent
commit
283fd6e2f9
  1. 119
      src/UnitTests/ArgumentCheckContract.cs
  2. 37
      src/UnitTests/FunctionalHelpers.cs
  3. 2
      src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs
  4. 6
      src/UnitTests/InterpolationTests/InterpolationInfrastructureContract.cs
  5. 3
      src/UnitTests/UnitTests.csproj

119
src/UnitTests/ArgumentCheckContract.cs

@ -0,0 +1,119 @@
// <copyright file="ArgumentCheckContract.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009 Math.NET
//
// 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.
// </copyright>
namespace MathNet.Numerics.UnitTests
{
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
internal class ArgumentCheckContract<T> : AbstractContract
{
public Expression<Func<T>> TypicalUse { get; set; }
public Expression<Func<T>>[] TypicalUses { get; set; }
public Func<T> BadUse { get; set; }
public Func<T>[] BadUses { get; set; }
protected override IEnumerable<Test> GetContractVerificationTests()
{
if (TypicalUse != null)
{
yield return CreateNullArgumentCheckTest(TypicalUse);
}
if (TypicalUses != null)
{
foreach (var typicalUse in TypicalUses)
{
yield return CreateNullArgumentCheckTest(typicalUse);
}
}
if (BadUse != null)
{
yield return CreateBadArgumentCheckTest(BadUse);
}
if (BadUses != null)
{
foreach (var badUse in BadUses)
{
yield return CreateBadArgumentCheckTest(badUse);
}
}
}
private static Test CreateNullArgumentCheckTest(Expression<Func<T>> typicalUse)
{
return new TestCase(
"NullArgumentCheck " + typicalUse.Body,
() =>
{
Assert.DoesNotThrow(() => typicalUse.Compile()());
// we only support method calls and constructors for now.
if (typicalUse.Body.NodeType != ExpressionType.New
&& typicalUse.Body.NodeType != ExpressionType.Call)
{
Assert.Fail(
"Subject '{0}' is neither a constructor or a method call.",
typicalUse.ToString());
return;
}
var badUses = typicalUse.ApplySingleMapEachArgument<T>(
t => !t.IsValueType,
e => Expression.Constant(null, e.Type));
foreach (var badUse in badUses)
{
var closureBadUseReference = badUse;
Assert.Throws(
typeof (ArgumentNullException),
() => closureBadUseReference.Compile()(),
"Subject '{0}' must check for null arguments",
closureBadUseReference.ToString());
}
});
}
private static Test CreateBadArgumentCheckTest(Func<T> badUse)
{
return new TestCase(
"BadArgumentCheck " + badUse.Method,
() => Assert.Throws(
typeof (ArgumentException),
() => badUse(),
"Subject '{0}' must check for bad arguments",
badUse.ToString()));
}
}
}

37
src/UnitTests/InterpolationTests/FunctionalHelpers.cs → src/UnitTests/FunctionalHelpers.cs

@ -26,13 +26,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System.Collections.Generic;
using System.Linq.Expressions;
using MathNet.Numerics.Interpolation;
namespace MathNet.Numerics.UnitTests.InterpolationTests
namespace MathNet.Numerics.UnitTests
{
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
internal static class FunctionalHelpers
{
@ -50,16 +48,24 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests
return newList;
}
internal static IEnumerable<Expression<Func<IInterpolation>>> ApplySingleMapEachArgument(
internal static IEnumerable<Expression<Func<T>>> ApplySingleMapEachArgument<T>(
this LambdaExpression lambda,
Func<Type, bool> predicate,
Func<Expression, Expression> replace)
{
var body = lambda.Body;
var bodyCall = body as MethodCallExpression;
var bodyCtor = body as NewExpression;
if (bodyCall == null && bodyCtor == null)
{
throw new NotSupportedException();
}
var arguments =
body is NewExpression
? ((NewExpression)body).Arguments
: ((MethodCallExpression)body).Arguments;
bodyCall != null
? bodyCall.Arguments
: bodyCtor.Arguments;
for (int i = 0; i < arguments.Count; i++)
{
@ -70,13 +76,14 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests
var mappedArguments = ApplySingleMap(arguments, i, replace);
yield return Expression.Lambda<Func<IInterpolation>>(
body is NewExpression
? (Expression)Expression.New(
((NewExpression)body).Constructor,
yield return Expression.Lambda<Func<T>>(
bodyCtor != null
? (Expression) Expression.New(
bodyCtor.Constructor,
mappedArguments)
: (Expression)Expression.Call(
((MethodCallExpression)body).Method,
: (Expression) Expression.Call(
bodyCall.Object,
bodyCall.Method,
mappedArguments));
}
}

2
src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs

@ -141,7 +141,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
VerifyIsReversibleReal(
0x80,
1e-10,
1e-9,
s => dht.NaiveForward(s, options),
s => dht.NaiveInverse(s, options));
}

6
src/UnitTests/InterpolationTests/InterpolationInfrastructureContract.cs

@ -112,7 +112,7 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests
continue;
}
var modifiedFactories = factory.ApplySingleMapEachArgument(
var modifiedFactories = factory.ApplySingleMapEachArgument<IInterpolation>(
t => !t.IsValueType,
e => Expression.Constant(null, e.Type));
@ -148,7 +148,7 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests
continue;
}
var modifiedFactories = factory.ApplySingleMapEachArgument(
var modifiedFactories = factory.ApplySingleMapEachArgument<IInterpolation>(
t => !t.IsValueType,
e => Expression.Constant(new double[MinimumSampleCount - 1], typeof(double[])));
@ -194,7 +194,7 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests
continue;
}
var modifiedFactories = factory.ApplySingleMapEachArgument(
var modifiedFactories = factory.ApplySingleMapEachArgument<IInterpolation>(
t => !t.IsValueType,
e =>
{

3
src/UnitTests/UnitTests.csproj

@ -59,6 +59,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ArgumentCheckContract.cs" />
<Compile Include="AssertHelpers.cs" />
<Compile Include="CombinatoricsTests\CombinatoricsCountingTest.cs" />
<Compile Include="ComplexTests\ComplexTest.cs" />
@ -74,7 +75,7 @@
<Compile Include="IntegralTransformsTests\InverseTransformTest.cs" />
<Compile Include="IntegralTransformsTests\SampleProvider.cs" />
<Compile Include="IntegrationTests\IntegrationTest.cs" />
<Compile Include="InterpolationTests\FunctionalHelpers.cs" />
<Compile Include="FunctionalHelpers.cs" />
<Compile Include="InterpolationTests\InterpolationInfrastuctureTest.cs" />
<Compile Include="InterpolationTests\InterpolationFunctionalContract.cs" />
<Compile Include="InterpolationTests\InterpolationInfrastructureContract.cs" />

Loading…
Cancel
Save