Exemple #1
0
        public override void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
        {
            foreach (MethodInfo method in TypeHelper.GetAttributedMethods(t, typeof(RepeatTestAttribute)))
            {
                try
                {
                    foreach (RepeatTestAttribute rep in method.GetCustomAttributes(typeof(RepeatTestAttribute), true))
                    {
                        for (int i = 0; i < rep.Count; i++)
                        {
                            // Get invoker
                            IRunInvoker invoker = new RepeatMethodRunInvoker(this, method, i + 1);

                            // Decorate invoker
                            invoker = DecoratorPatternAttribute.DecoreInvoker(method, invoker);

                            // Add to tree
                            tree.AddChild(parent, invoker);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MethodFailedLoadingRunInvoker invoker = new MethodFailedLoadingRunInvoker(this, ex, method);
                    tree.AddChild(parent, invoker);
                }
            }
        }
		/// <summary>
		/// Populates the <see cref="RunInvokerTree"/> invoker graph
		/// with <see cref="IRunInvoker"/> generated by the run.
		/// </summary>
		/// <param name="tree">Invoker tree</param>
		/// <param name="parent">parent vertex</param>
		/// <param name="t">class type that is marked by the run</param>
		/// <remarks>
		/// </remarks>
		public void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
		{
			foreach(MethodInfo mi in 
				TypeHelper.GetAttributedMethods(t,typeof(IndexerProviderAttribute)))
			{
				// get attribute
				IndexerProviderAttribute attr = 
					(IndexerProviderAttribute)TypeHelper.GetFirstCustomAttribute(mi,typeof(IndexerProviderAttribute));
				
				// add indexer provider
				IRunInvoker invoker = 
					new ArgumentFeederRunInvoker(this,mi);
				RunInvokerVertex child = 
						tree.AddChild(parent,invoker);				
				
				// add tester
				CustomRun testerRun = new CustomRun(
					this.testerType,
					typeof(TestAttribute),
					true,
					attr
					);
				testerRun.Reflect(tree,child,t);
			}
		}
Exemple #3
0
        public void Load(IRunPipeFilter filter)
        {
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }

            this.starters.Clear();
            try
            {
                RunInvokerTree tree = new RunInvokerTree(this);

                foreach (RunPipe pipe in tree.AllTestPipes())
                {
                    if (!filter.Filter(pipe))
                    {
                        continue;
                    }

                    RunPipeStarter starter = new RunPipeStarter(pipe);
                    this.Starters.Add(starter);
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Error while create the invoker tree", ex);
            }
        }
Exemple #4
0
 public TestTreeArgs(RunInvokerTree tree, RunInvokerVertex parent, Type type_that_contains_tests, IRun run)
 {
     this.tree   = tree;
     this.parent = parent;
     this.type_that_contains_tests = type_that_contains_tests;
     this.run = run;
 }
Exemple #5
0
 public override void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
 {
     foreach (MethodInfo mi in TypeHelper.GetAttributedMethods(t, this.framework.TestAttributeType))
     {
         IRunInvoker invoker = this.CreateInvoker(mi);
         tree.AddChild(parent, invoker);
     }
 }
Exemple #6
0
 public void Reflect(
     RunInvokerTree tree,
     RunInvokerVertex parent,
     Type t
     )
 {
     PopulateInvokerTree(tree, parent, t);
 }
Exemple #7
0
        public void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
        {
            FailedLoadingRunInvoker invoker = new FailedLoadingRunInvoker(
                this,
                this.exception
                );

            tree.AddChild(parent, invoker);
        }
Exemple #8
0
        private void PopulateInvokerTree(
            RunInvokerTree tree,
            RunInvokerVertex parent,
            Type t
            )
        {
            // Try and find setup method
            MethodRunInvoker setup = null;

            if (TypeHelper.HasMethodCustomAttribute(t, typeof(SetUpAttribute)))
            {
                setup = new MethodRunInvoker(this, TypeHelper.GetAttributedMethod(t, typeof(SetUpAttribute)));
            }

            // Gather all methods, with order.
            ArrayList methods = new ArrayList();

            foreach (MethodInfo mi in
                     TypeHelper.GetAttributedMethods(t, this.AttributeType))
            {
                // get sequence attribute
                TestSequenceAttribute seq =
                    (TestSequenceAttribute)TypeHelper.GetFirstCustomAttribute(mi, typeof(TestSequenceAttribute));
                methods.Add(new OrderedMethod(mi, seq.Order));
            }

            // sort the methods
            QuickSorter sorter = new QuickSorter();

            sorter.Sort(methods);

            // Try and find teardown method
            MethodRunInvoker teardown = null;

            if (TypeHelper.HasMethodCustomAttribute(t, typeof(TearDownAttribute)))
            {
                teardown = new MethodRunInvoker(this, TypeHelper.GetAttributedMethod(t, typeof(TearDownAttribute)));
            }

            // populate execution tree.
            RunInvokerVertex child = parent;

            foreach (OrderedMethod om in methods)
            {
                if (setup != null)
                {
                    child = tree.AddChild(child, setup);
                }

                child = tree.AddChild(child, InstanceInvoker(om.Method));

                if (teardown != null)
                {
                    child = tree.AddChild(child, teardown);
                }
            }
        }
Exemple #9
0
 public virtual void Reflect(
     RunInvokerTree tree,
     RunInvokerVertex parent,
     Type t
     )
 {
     CheckType(t);
     PopulateInvokerTree(tree, parent, t);
 }
Exemple #10
0
        public override void Reflect(
            RunInvokerTree tree,
            RunInvokerVertex parent,
            Type t)
        {
            // create type instance and create test suite
            Object fixture = null;

            try
            {
                fixture = TypeHelper.CreateInstance(t);

                // run TestSuiteSetUp if necessary
                MethodInfo testSuiteSetUp = TypeHelper.GetAttributedMethod(t, typeof(TestSuiteSetUpAttribute));
                if (testSuiteSetUp != null)
                {
                    testSuiteSetUp.Invoke(fixture, null);
                }

                // look for SetUp & TearDown methods
                MethodInfo setUp    = TypeHelper.GetAttributedMethod(t, typeof(SetUpAttribute));
                MethodInfo tearDown = TypeHelper.GetAttributedMethod(t, typeof(TearDownAttribute));

                // explore type for methods with TestSuite
                foreach (MethodInfo mi in TypeHelper.GetAttributedMethods(t, typeof(TestSuiteAttribute)))
                {
                    // check signature
                    TypeHelper.CheckSignature(mi, typeof(ITestSuite));

                    // get test suite
                    ITestSuite suite = mi.Invoke(fixture, null) as ITestSuite;
                    Assert.IsNotNull(suite, "TestSuite method cannot return null");

                    // populated tree down...
                    foreach (ITestCase tc in suite.TestCases)
                    {
                        tree.AddChild(parent, new TestCaseRunInvoker(this, suite, tc, setUp, tearDown));
                    }
                }
            }
            catch (Exception ex)
            {
                TestSuiteGenerationFailedRunInvoker invoker = new TestSuiteGenerationFailedRunInvoker(this, ex);
                tree.AddChild(parent, invoker);
            }
            finally
            {
                IDisposable disposable = fixture as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }
Exemple #11
0
 protected override void PopulateInvokerTree(
     RunInvokerTree tree,
     RunInvokerVertex parent,
     Type t
     )
 {
     if (TypeHelper.HasMethodCustomAttribute(t, this.AttributeType))
     {
         MethodInfo mi = TypeHelper.GetAttributedMethod(t, this.AttributeType);
         tree.AddChild(parent, new MethodRunInvoker(this, mi));
     }
 }
 /// <summary>
 /// Populates the <see cref="RunInvokerTree"/> invoker graph
 /// with <see cref="IRunInvoker"/> generated by the run.
 /// </summary>
 /// <param name="tree">Invoker tree</param>
 /// <param name="parent">parent vertex</param>
 /// <param name="t">class type that is marked by the run</param>
 public override void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
 {
     foreach (MethodInfo grammar in TypeHelper.GetAttributedMethods(t, typeof(GrammarAttribute)))
     {
         foreach (MethodInfo seed in TypeHelper.GetAttributedMethods(t, typeof(SeedAttribute)))
         {
             ProductionGrammarRunInvoker invoker =
                 new ProductionGrammarRunInvoker(this, grammar, seed);
             tree.AddChild(parent, invoker);
         }
     }
 }
Exemple #13
0
            public override void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
            {
                MethodInfo method = t.GetMethod(this.methodName, Type.EmptyTypes);

                if (method == null)
                {
                    return;
                }
                MethodRunInvoker invoker          = new MethodRunInvoker(this, method);
                IRunInvoker      decoratedInvoker = DecoratorPatternAttribute.DecoreInvoker(method, invoker);

                tree.AddChild(parent, decoratedInvoker);
            }
Exemple #14
0
        protected virtual void PopulateInvokerTree(
            RunInvokerTree tree,
            RunInvokerVertex parent,
            Type t
            )
        {
            if (this.AllowMultiple)
            {
                foreach (MethodInfo mi in
                         TypeHelper.GetAttributedMethods(t, this.AttributeType))
                {
                    try
                    {
                        if (this.Checker != null)
                        {
                            this.Checker.Check(mi);
                        }

                        IRunInvoker      invoker = InstanceInvoker(mi);
                        RunInvokerVertex child   =
                            tree.AddChild(parent, invoker);
                    }
                    catch (Exception ex)
                    {
                        FailedLoadingRunInvoker invoker = new FailedLoadingRunInvoker(
                            this, ex);
                        tree.AddChild(parent, invoker);
                    }
                }
            }
            else
            {
                try
                {
                    MethodInfo mi = TypeHelper.GetAttributedMethod(t, this.AttributeType);
                    if (this.Checker != null)
                    {
                        this.Checker.Check(mi);
                    }

                    tree.AddChild(parent, new MethodRunInvoker(this, mi));
                }
                catch (Exception ex)
                {
                    FailedLoadingRunInvoker invoker = new FailedLoadingRunInvoker(
                        this, ex);
                    tree.AddChild(parent, invoker);
                }
            }
        }
Exemple #15
0
        public void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
        {
            // getting properties from the factory that returns a
            // type assignable to factored type
            foreach (PropertyInfo pi in TypeHelper.GetAttributedProperties(this.factoryType, typeof(FactoryAttribute)))
            {
                // make sure readable
                if (!pi.CanRead)
                {
                    continue;
                }
                // check return type
                if (!this.factoredType.IsAssignableFrom(pi.PropertyType))
                {
                    continue;
                }
                // check it is not an index
                if (pi.GetGetMethod().GetParameters().Length != 0)
                {
                    continue;
                }

                // ok, we can add this one to the tree
                PropertyGetRunInvoker pget = new PropertyGetRunInvoker(
                    this,
                    pi
                    );
                tree.AddChild(parent, pget);
            }

/*
 *                      // getting methods
 *          foreach (MethodInfo mi in TypeHelper.GetAttributedProperties(this.factoredType, typeof(FactoryAttribute)))
 *          {
 *                              if (mi.GetParameters().Length!=0)
 *                                      continue;
 *                              if (!this.factoredType.IsAssignableFrom(mi.ReturnType))
 *                                      continue;
 *                              if (mi.Name.StartsWith("get_"))
 *                                      continue;
 *
 *                              ArgumentFeederRunInvoker mrun = new ArgumentFeederRunInvoker(
 *                                      this,
 *                                      mi
 *                                      );
 *                              tree.AddChild(parent,mrun);
 *                      }
 */
        }
Exemple #16
0
            public override void Reflect(
                RunInvokerTree tree,
                RunInvokerVertex parent,
                Type t
                )
            {
                // populate execution tree.
                RunInvokerVertex child = parent;

                foreach (MethodInfo mi in
                         TypeHelper.GetAttributedMethods(t, typeof(StepAttribute)))
                {
//						IRunInvoker invoker = InstanceInvoker(om.Method);
//						child = tree.AddChild(child,invoker);
                }
            }
Exemple #17
0
 /// <summary>
 /// Populates the <see cref="RunInvokerTree"/> invoker graph
 /// with <see cref="IRunInvoker"/> generated by the run.
 /// </summary>
 /// <remarks>
 /// Inherited method from base class Run
 /// </remarks>
 /// <param name="tree">Invoker tree.</param>
 /// <param name="parent">Parent vertex.</param>
 /// <param name='t'>The <see cref="Type"/> to search for.</param>
 public void Reflect(
     RunInvokerTree tree,
     RunInvokerVertex parent,
     Type t
     )
 {
     // for each run
     foreach (IRun run in this.Runs)
     {
         // for each leaf
         foreach (RunInvokerVertex leaf in tree.Leaves(parent))
         {
             // add runs
             run.Reflect(tree, leaf, t);
         }
     }
 }
Exemple #18
0
 public void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
 {
     // add tests methods
     foreach (MethodInfo mi in TypeHelper.GetAttributedMethods(
                  this.testerType,
                  this.targetAttributeType)
              )
     {
         CustomRunInvoker cr = new CustomRunInvoker(
             this,
             InstanceTester(),
             mi,
             this.feedSender
             );
         // adding decoration and to tree
         tree.AddChild(parent,
                       DecoratorPatternAttribute.DecoreInvoker(mi, cr)
                       );
     }
 }
Exemple #19
0
            public override void Reflect(
                RunInvokerTree tree,
                RunInvokerVertex parent,
                Type t)
            {
                foreach (MethodInfo method in t.GetMethods())
                {
                    if (method.IsSpecialName)
                    {
                        continue;
                    }
                    if (!method.Name.EndsWith(this.methodNameSuffix))
                    {
                        continue;
                    }

                    MethodRunInvoker invoker          = new MethodRunInvoker(this, method);
                    IRunInvoker      decoratedInvoker = DecoratorPatternAttribute.DecoreInvoker(method, invoker);
                    tree.AddChild(parent, decoratedInvoker);
                }
            }
Exemple #20
0
 public void Reflect(
     RunInvokerTree tree,
     RunInvokerVertex parent,
     Type t
     )
 {
     if (this.runs.Count == 0 && !this.allowEmpty)
     {
         throw new InvalidOperationException("Parralel run is empty. Missing factory ?");
     }
     // for each leaf
     foreach (RunInvokerVertex leaf in tree.Leaves(parent))
     {
         // for each run
         foreach (IRun run in this.Runs)
         {
             // add runs
             run.Reflect(tree, leaf, t);
         }
     }
 }
Exemple #21
0
        /// <summary>
        /// Builds the test run invoker tree.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="parent"></param>
        /// <param name="t"></param>
        public override void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
        {
            // Cache these runs because we reuse them for every test fixture.
            lock (syncRoot)
            {
                if (tearDownRun == null)
                {
                    setupRun = new OptionalMethodRun(typeof(SetUpAttribute), false);

                    object[] factories = GetType().GetCustomAttributes(typeof(RunFactoryAttribute), true);
                    testRuns = new IRun[factories.Length];
                    for (int i = 0; i < factories.Length; i++)
                    {
                        testRuns[i] = ((RunFactoryAttribute)factories[i]).CreateRun();
                    }

                    tearDownRun = new OptionalMethodRun(typeof(TearDownAttribute), false);
                }
            }

            // Build the sequence including any extensions and apply it.
            CreateSequence(t).Reflect(tree, parent, t);
        }
        public void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
        {
            if (tree == null)
            {
                throw new ArgumentNullException("tree");
            }
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }
            if (t == null)
            {
                throw new ArgumentNullException("t");
            }

            // for each attribute
            foreach (FixtureDecoratorPatternAttribute ca in t.GetCustomAttributes(this.decoratorType, true))
            {
                // populate tree
                IRun carun = ca.GetRun(t);
                carun.Reflect(tree, parent, t);
            }
        }
Exemple #23
0
        public override void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
        {
            object fixture = null;

            try
            {
                // Check if fixture is ignored or explicit
                IgnoreAttribute ignore = null;
                if (TypeHelper.HasCustomAttribute(t, typeof(IgnoreAttribute)))
                {
                    ignore = TypeHelper.GetFirstCustomAttribute(t, typeof(IgnoreAttribute)) as IgnoreAttribute;
                }
                ExplicitAttribute expl = null;
                if (TypeHelper.HasCustomAttribute(t, typeof(ExplicitAttribute)))
                {
                    expl = TypeHelper.GetFirstCustomAttribute(t, typeof(ExplicitAttribute)) as ExplicitAttribute;
                }

                foreach (MethodInfo method in TypeHelper.GetAttributedMethods(t, typeof(CombinatorialTestAttribute)))
                {
                    if (fixture == null)
                    {
                        fixture = TypeHelper.CreateInstance(t);
                    }

                    this.ReflectTestMethod(tree, parent, fixture, method, ignore, expl);
                }
            }
            finally
            {
                IDisposable disposable = fixture as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }
Exemple #24
0
        public override void Reflect(
            RunInvokerTree tree,
            RunInvokerVertex parent,
            Type t)
        {
            foreach (MethodInfo method in TypeHelper.GetAttributedMethods(t, typeof(RowTestAttribute)))
            {
                try
                {
                    foreach (RowAttribute row in method.GetCustomAttributes(typeof(RowAttribute), true))
                    {
                        // get invoker
                        IRunInvoker invoker = new RowMethodRunInvoker(
                            this,
                            method,
                            row
                            );
                        if (row.ExpectedException != null)
                        {
                            invoker = new ExpectedExceptionRunInvoker(
                                invoker, row.ExpectedException, row.Description
                                );
                        }
                        // decore invoker
                        invoker = DecoratorPatternAttribute.DecoreInvoker(method, invoker);

                        tree.AddChild(parent, invoker);
                    }
                }
                catch (Exception ex)
                {
                    MethodFailedLoadingRunInvoker invoker = new MethodFailedLoadingRunInvoker(this, ex, method);
                    tree.AddChild(parent, invoker);
                }
            }
        }
Exemple #25
0
        public void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
        {
            // getting methods
            ICollection mis = TypeHelper.GetAttributedMethods(
                t,
                typeof(ForEachTestAttribute)
                );

            // first get the DataProviderFixtureDecorator...
            foreach (DataProviderFixtureDecoratorAttribute dp in
                     t.GetCustomAttributes(typeof(DataProviderFixtureDecoratorAttribute), true))
            {
                // for each node
                foreach (XmlNode node in dp.GetData())
                {
                    // for each test method
                    foreach (MethodInfo mi in mis)
                    {
                        // get attribute
                        ForEachTestAttribute fe =
                            (ForEachTestAttribute)TypeHelper.GetFirstCustomAttribute(
                                mi, typeof(ForEachTestAttribute));
                        // select nodes
                        foreach (XmlNode childNode in node.SelectNodes(fe.XPath))
                        {
                            // create invokers
                            IRunInvoker invoker = new ForEachTestRunInvoker(this, mi, fe, childNode);
                            //decorage
                            invoker = DecoratorPatternAttribute.DecoreInvoker(mi, invoker);
                            // add invoker
                            tree.AddChild(parent, invoker);
                        }
                    }
                }
            }
        }
            public override void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
            {
                if (!typeof(IComponent).IsAssignableFrom(t))
                {
                    throw new ArgumentException("Fixture type implement IComponent", t.FullName);
                }

                // get set up or tearown
                // look
                MethodInfo setUp    = TypeHelper.GetAttributedMethod(t, typeof(SetUpAttribute));
                MethodInfo tearDown = TypeHelper.GetAttributedMethod(t, typeof(TearDownAttribute));

                using (IComponent fixture = (IComponent)TypeHelper.CreateInstance(t))
                {
                    // get components field
                    FieldInfo componentsField = t.GetField("components",
                                                           BindingFlags.Instance | BindingFlags.NonPublic);
                    if (componentsField == null)
                    {
                        return;
                    }
                    // call InitializeMethod
                    MethodInfo initialzeComponent = t.GetMethod("InitializeComponent",
                                                                BindingFlags.Instance | BindingFlags.NonPublic);
                    if (initialzeComponent != null)
                    {
                        initialzeComponent.Invoke(fixture, null);
                    }

                    IContainer components = componentsField.GetValue(fixture) as IContainer;
                    if (components == null)
                    {
                        return;
                    }

                    ArrayList suites = new ArrayList();
                    // get suites
                    foreach (IComponent component in components.Components)
                    {
                        // get component
                        ITestComponent testComponent = component as ITestComponent;
                        if (testComponent == null)
                        {
                            continue;
                        }

                        // get test suite
                        ITestSuite testSuite = testComponent.GetTests();
                        if (testSuite == null)
                        {
                            continue;
                        }
                        suites.Add(testSuite);
                    }

                    // decorate
                    foreach (IComponent component in components.Components)
                    {
                        ITestDecoratorComponent decorator = component as ITestDecoratorComponent;
                        if (decorator == null)
                        {
                            continue;
                        }

                        for (int i = 0; i < suites.Count; ++i)
                        {
                            suites[i] = decorator.Decorate((ITestSuite)suites[i]);
                        }
                    }

                    // add suites
                    foreach (ITestSuite testSuite in suites)
                    {
                        foreach (ITestCase testCase in testSuite.TestCases)
                        {
                            TestCaseRunInvoker invoker = new TestCaseRunInvoker(
                                this, testSuite, testCase, setUp, tearDown);
                            tree.AddChild(parent, invoker);
                        }
                    }
                }
            }
Exemple #27
0
 public void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
 {
     throw new Exception("not implemented");
 }
Exemple #28
0
 public override void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
 {
     block_action.run_against(new TestTreeArgs <DelegateType>(tree, parent, t, main_run));
 }
Exemple #29
0
 /// <summary>
 /// Populates the <see cref="RunInvokerTree"/> invoker graph
 /// with <see cref="IRunInvoker"/> generated by the run. <b>Not supported</b> in this class
 /// </summary>
 /// <param name="tree">Invoker tree</param>
 /// <param name="parent">parent vertex</param>
 /// <param name="t">class type that is marked by the run</param>
 /// <remarks>
 /// Not Supported by the <see cref="TestCaseRun"/> class.
 /// </remarks>
 public override void Reflect(RunInvokerTree tree, RunInvokerVertex parent, Type t)
 {
     throw new NotSupportedException();
 }
Exemple #30
0
        private void ReflectTestMethod(
            RunInvokerTree tree,
            RunInvokerVertex parent,
            object fixture,
            MethodInfo method,
            IgnoreAttribute ignore,
            ExplicitAttribute expl)
        {
            // Check if fixture/method is ignored/explicit
            if (ignore == null && TypeHelper.HasCustomAttribute(method, typeof(IgnoreAttribute)))
            {
                ignore = TypeHelper.GetFirstCustomAttribute(method, typeof(IgnoreAttribute)) as IgnoreAttribute;
            }
            if (expl == null && TypeHelper.HasCustomAttribute(method, typeof(ExplicitAttribute)))
            {
                expl = TypeHelper.GetFirstCustomAttribute(method, typeof(ExplicitAttribute)) as ExplicitAttribute;
            }

            if (ignore != null)
            {
                // Do not generate unnecessary test cases
                IgnoredLoadingRunInvoker invoker = new IgnoredLoadingRunInvoker(this, method, ignore.Description);
                tree.AddChild(parent, invoker);
            }
            else if (expl != null)
            {
                // Do not generate unnecessary test cases
                IgnoredLoadingRunInvoker invoker = new IgnoredLoadingRunInvoker(this, method, expl.Description);
                tree.AddChild(parent, invoker);
            }
            else
            {
                CombinatorialTestAttribute testAttribute = TypeHelper.GetFirstCustomAttribute(method, typeof(CombinatorialTestAttribute))
                                                           as CombinatorialTestAttribute;

                ParameterInfo[] parameters = method.GetParameters();
                if (parameters.Length == 0)
                {
                    Exception ex = new Exception("No parameters");
                    MethodFailedLoadingRunInvoker invoker = new MethodFailedLoadingRunInvoker(this, ex, method);
                    tree.AddChild(parent, invoker);
                    return;
                }

                // create the models
                DomainCollection domains        = new DomainCollection();
                Type[]           parameterTypes = new Type[parameters.Length];
                int index = 0;
                foreach (ParameterInfo parameter in parameters)
                {
                    parameterTypes[index] = parameter.ParameterType;

                    DomainCollection pdomains = new DomainCollection();
                    foreach (UsingBaseAttribute usingAttribute in parameter.GetCustomAttributes(typeof(UsingBaseAttribute), true))
                    {
                        try
                        {
                            usingAttribute.GetDomains(pdomains, parameter, fixture);
                        }
                        catch (Exception ex)
                        {
                            Exception pex = new Exception("Failed while loading domains from parameter " + parameter.Name,
                                                          ex);
                            MethodFailedLoadingRunInvoker invoker = new MethodFailedLoadingRunInvoker(this, pex, method);
                            tree.AddChild(parent, invoker);
                        }
                    }
                    if (pdomains.Count == 0)
                    {
                        Exception ex = new Exception("Could not find domain for argument " + parameter.Name);
                        MethodFailedLoadingRunInvoker invoker = new MethodFailedLoadingRunInvoker(this, ex, method);
                        tree.AddChild(parent, invoker);
                        return;
                    }
                    domains.Add(Domains.ToDomain(pdomains));

                    index++;
                }

                // get the validator method if any
                MethodInfo validator = null;
                if (testAttribute.TupleValidatorMethod != null)
                {
                    validator = fixture.GetType().GetMethod(testAttribute.TupleValidatorMethod, parameterTypes);
                    if (validator == null)
                    {
                        Exception ex = new Exception("Could not find validator method " + testAttribute.TupleValidatorMethod);
                        MethodFailedLoadingRunInvoker invoker = new MethodFailedLoadingRunInvoker(this, ex, method);
                        tree.AddChild(parent, invoker);
                        return;
                    }
                }

                // we make a cartesian product of all those
                foreach (ITuple tuple in Products.Cartesian(domains))
                {
                    // create data domains
                    DomainCollection tdomains = new DomainCollection();
                    for (int i = 0; i < tuple.Count; ++i)
                    {
                        IDomain dm = (IDomain)tuple[i];
                        tdomains.Add(dm);
                    }

                    // computing the pairwize product
                    foreach (ITuple ptuple in testAttribute.GetProduct(tdomains))
                    {
                        if (validator != null)
                        {
                            bool isValid = (bool)validator.Invoke(fixture, ptuple.ToObjectArray());
                            if (!isValid)
                            {
                                continue;
                            }
                        }

                        TupleRunInvoker invoker  = new TupleRunInvoker(this, method, tuple, ptuple);
                        IRunInvoker     dinvoker = DecoratorPatternAttribute.DecoreInvoker(method, invoker);
                        tree.AddChild(parent, dinvoker);
                    }
                }
            }
        }