rakete
rakete

Reputation: 3041

Need some help for planning class model

I want to declare some functions for tests. For example:

CountWords(string text)
ExistsWordInText(string text, string searchedWord)
CountOfWord(string text, string searchedWord)

Now I want to declare "testdefintions". These testdefinitions will be added to a collection and include a function and, depending on the function, different parameters.

A method will now execute all the tests from the testdefintions collection and the tests will return a result.

I want to add functions in the future without changing anything else.

At the moment I am at this point:

IFunction-interface

public interface IFunction
{
    #region Methods

    void Run();

    #endregion
}

Any function

public class AttributeExistenceFunction : FunctionBase
{
    public override void Run() {
        // Do any test
        throw new FormatException();
    }
}

TestDefinition-Class

public class TestDefinition : ITestDefinition
{
    #region Fields

    public IFunction Function { get; set; }

    #endregion

    #region Constructor

    public TestDefinition(IFunction function)
    {
        this.Function = function;
    }

    #endregion

    #region Methods

    public void Run(Uri site)
    {
        this.Function.Run();
    }

    #endregion
}

Has anybody an idea how to realize the dynamic paramters / results?

Upvotes: 0

Views: 313

Answers (1)

YoryeNathan
YoryeNathan

Reputation: 14522

I started it out optimistic, but it turned out really ugly.

I'll post it anyways since it does the job after all.

You can easily add Func constructors to support Action and lose the VoidReturn hack.

public class Func
{
    public readonly MethodInfo Method;
    public readonly object Target;

    #region Ctors

    public static Func Get<TResult>(Func<TResult> func)
    {
        return new Func(func.Method, func.Target);
    }

    public static Func Get<T, TResult>(Func<T, TResult> func)
    {
        return new Func(func.Method, func.Target);
    }

    public static Func Get<T1, T2, TResult>(Func<T1, T2, TResult> func)
    {
        return new Func(func.Method, func.Target);
    }

    public static Func Get<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func)
    {
        return new Func(func.Method, func.Target);
    }

    #endregion

    private Func(MethodInfo method, object target)
    {
        this.Method = method;
        this.Target = target;
    }

    public object Run(params object[] parameters)
    {
        return this.Method.Invoke(this.Target, parameters);
    }
}

public class MyClass
{
    public string Data { get; set; }

    public int Add(int x, int y)
    {
        return x + y;
    }

    public bool IsZero(int i)
    {
        return i == 0;
    }

    public void Print(object msg)
    {
        Console.WriteLine(msg);
    }

    public bool ValidateData()
    {
        return string.IsNullOrEmpty(this.Data);
    }

    public void TestMethods()
    {
        var tests = new Dictionary<Func, object[][]>
                        {
                            {
                                Func.Get<int, int, int>(this.Add),
                                new[]
                                    {
                                        new object[] {2, 3},
                                        new object[] {5, 0},
                                        new object[] {10, -2}
                                    }
                                },
                            {
                                Func.Get<int, bool>(this.IsZero),
                                new[]
                                    {
                                        new object[] {1},
                                        new object[] {0},
                                        new object[] {-1}
                                    }
                                },
                            {
                                Func.Get<object, VoidReturn>(o =>
                                                                 {
                                                                     this.Print(o);
                                                                     return VoidReturn.Blank;
                                                                 }),
                                new[]
                                    {
                                        new object[] {"Msg1"},
                                        new object[] {"Msg2"},
                                        new object[] {"Msg3"}
                                    }
                                },
                            {Func.Get(this.ValidateData), null}
                        };


        foreach (var testFunc in tests)
        {
            Console.WriteLine("Testing method: " + testFunc.Key.Method.Name);
            Console.WriteLine();

            foreach (var parameters in testFunc.Value)
            {
                Console.WriteLine("Parameters: " + string.Join(", ", parameters));

                var result = testFunc.Key.Run(parameters);

                Console.WriteLine(result is VoidReturn ? "*void" : ("Returned: " + result));
                Console.WriteLine();
            }

            Console.WriteLine("________________________________");
            Console.WriteLine();
        }
    }

    private enum VoidReturn
    {
        Blank
    }
}

Upvotes: 1

Related Questions