Example #1
0
        private void finishLoad(TestScene newTest, Action onCompletion)
        {
            if (CurrentTest != newTest)
            {
                // There could have been multiple loads fired after us. In such a case we want to silently remove ourselves.
                testContentContainer.Remove(newTest.Parent);
                return;
            }

            updateButtons();

            bool hadTestAttributeTest = false;

            foreach (var m in newTest.GetType().GetMethods())
            {
                var name = m.Name;

                if (name == nameof(TestScene.TestConstructor) || m.GetCustomAttribute(typeof(IgnoreAttribute), false) != null)
                {
                    continue;
                }

                if (name.StartsWith("Test", StringComparison.Ordinal))
                {
                    name = name.Substring(4);
                }

                int runCount = 1;

                if (m.GetCustomAttribute(typeof(RepeatAttribute), false) != null)
                {
                    var count = m.GetCustomAttributesData().Single(a => a.AttributeType == typeof(RepeatAttribute)).ConstructorArguments.Single().Value;
                    Debug.Assert(count != null);

                    runCount += (int)count;
                }

                for (int i = 0; i < runCount; i++)
                {
                    string repeatSuffix = i > 0 ? $" ({i + 1})" : string.Empty;

                    var methodWrapper = new MethodWrapper(m.GetType(), m);

                    if (methodWrapper.GetCustomAttributes <TestAttribute>(false).SingleOrDefault() != null)
                    {
                        var parameters = m.GetParameters();

                        if (parameters.Length > 0)
                        {
                            var valueMatrix = new List <List <object> >();

                            foreach (var p in methodWrapper.GetParameters())
                            {
                                var valueAttrib = p.GetCustomAttributes <ValuesAttribute>(false).SingleOrDefault();
                                if (valueAttrib == null)
                                {
                                    throw new ArgumentException($"Parameter is present on a {nameof(TestAttribute)} method without values specification.", p.ParameterInfo.Name);
                                }

                                List <object> choices = new List <object>();

                                foreach (var choice in valueAttrib.GetData(p))
                                {
                                    choices.Add(choice);
                                }

                                valueMatrix.Add(choices);
                            }

                            foreach (var combination in valueMatrix.CartesianProduct())
                            {
                                hadTestAttributeTest = true;
                                CurrentTest.AddLabel($"{name}({string.Join(", ", combination)}){repeatSuffix}");
                                handleTestMethod(m, combination.ToArray());
                            }
                        }
                        else
                        {
                            hadTestAttributeTest = true;
                            CurrentTest.AddLabel($"{name}{repeatSuffix}");
                            handleTestMethod(m);
                        }
                    }

                    foreach (var tc in m.GetCustomAttributes(typeof(TestCaseAttribute), false).OfType <TestCaseAttribute>())
                    {
                        hadTestAttributeTest = true;
                        CurrentTest.AddLabel($"{name}({string.Join(", ", tc.Arguments)}){repeatSuffix}");

                        handleTestMethod(m, tc.Arguments);
                    }
                }
            }

            // even if no [Test] or [TestCase] methods were found, [SetUp] steps should be added.
            if (!hadTestAttributeTest)
            {
                addSetUpSteps();
            }

            backgroundCompiler?.SetRecompilationTarget(CurrentTest);
            runTests(onCompletion);
            updateButtons();

            void addSetUpSteps()
            {
                var setUpMethods = Reflect.GetMethodsWithAttribute(newTest.GetType(), typeof(SetUpAttribute), true)
                                   .Where(m => m.Name != nameof(TestScene.SetUpTestForNUnit));

                if (setUpMethods.Any())
                {
                    CurrentTest.AddStep(new SingleStepButton(true)
                    {
                        Text        = "[SetUp]",
                        LightColour = Color4.Teal,
                        Action      = () => setUpMethods.ForEach(s => s.Invoke(CurrentTest, null))
                    });
                }

                CurrentTest.RunSetUpSteps();
            }

            void handleTestMethod(MethodInfo methodInfo, object[] arguments = null)
            {
                addSetUpSteps();
                methodInfo.Invoke(CurrentTest, arguments);
                CurrentTest.RunTearDownSteps();
            }
        }