/// <summary>
        /// Draws the given errors.
        /// </summary>
        /// <param name="errors">The errors.</param>
        /// <param name="unityInterface">The unity interface.</param>
        public void Errors(List <UnityTestBDDError> errors, IUnityInterfaceWrapper unityInterface)
        {
            BDDExtensionRunner bddExtensionRunner = this.component.gameObject.GetComponent <BDDExtensionRunner>();
            string             openComponentButtonTextureFullPath = Utilities.GetAssetFullPath(bddExtensionRunner, this.OpenComponentButtonTextureFileName);
            string             errorTextureFullPath = Utilities.GetAssetFullPath(bddExtensionRunner, this.ErrorTextureFileName);

            foreach (UnityTestBDDError error in errors)
            {
                unityInterface.EditorGUILayoutBeginHorizontal();
                unityInterface.EditorGUILayoutSeparator();
                unityInterface.EditorGUILayoutSeparator();
                unityInterface.EditorGUILayoutEndHorizontal();
                unityInterface.EditorGUILayoutBeginHorizontal();
                float             currentViewWidth    = unityInterface.EditorGUIUtilityCurrentViewWidth();
                Texture2D         errorTexture        = unityInterface.AssetDatabaseLoadAssetAtPath(errorTextureFullPath, typeof(Texture2D));
                GUILayoutOption[] errorTextureOptions = new GUILayoutOption[2] {
                    unityInterface.GUILayoutWidth(24), unityInterface.GUILayoutHeight(24)
                };
                unityInterface.EditorGUILayoutLabelField(errorTexture, errorTextureOptions);
                float labelWidth = currentViewWidth - 100;
                unityInterface.EditorGUILayoutLabelField(error.Message, labelWidth);

                Texture2D         openComponentButtonTexture = unityInterface.AssetDatabaseLoadAssetAtPath(openComponentButtonTextureFullPath, typeof(Texture2D));
                GUILayoutOption[] options = new GUILayoutOption[2] {
                    unityInterface.GUILayoutWidth(24), unityInterface.GUILayoutHeight(24)
                };
                if (unityInterface.GUILayoutButton(openComponentButtonTexture, EditorStyles.label, options))
                {
                    if (error.MethodMethodInfo != null)
                    {
                        SourcesManagement.OpenMethodSourceCode(error.MethodMethodInfo, unityInterface);
                    }
                    else if (error.Component != null)
                    {
                        SourcesManagement.OpenSourceCode(error.Component, unityInterface);
                    }
                    else
                    {
                        MethodInfo[] methods = this.component.GetType().GetMethods();
                        foreach (MethodInfo method in methods)
                        {
                            if (method.DeclaringType.Name.Equals(this.component.GetType().Name))
                            {
                                SourcesManagement.OpenSourceCode(method, unityInterface);
                            }
                        }
                    }
                }

                unityInterface.EditorGUILayoutEndHorizontal();
            }
        }
        public void DrawStaticRows_Should_CallTheRightUnityEditoStatements_Given_AStaticComponentWithTwoWhenMethods()
        {
            Component[] bddComponents = new Component[1] {
                UnitTestUtility.CreateComponent <RunnerEditorBusinessLogicStaticRowsTestStaticComponent>()
            };

            IUnityInterfaceWrapper unityInterface = Substitute.For <IUnityInterfaceWrapper>();

            unityInterface.EditorGUIUtilityCurrentViewWidth().Returns <float>(500F);

            BaseMethodDescriptionBuilder methodBuilder = Substitute.For <BaseMethodDescriptionBuilder>();

            BaseMethodDescriptionBuilder  baseMethodDescriptionBuilder  = new BaseMethodDescriptionBuilder();
            MethodsFilterByExecutionOrder methodsFilterByExecutionOrder = new MethodsFilterByExecutionOrder();
            MethodsLoader bddStepMethodsLoader = new MethodsLoader(baseMethodDescriptionBuilder, methodsFilterByExecutionOrder);
            List <BaseMethodDescription> baseMethodDescriptionList = bddStepMethodsLoader.LoadStepMethods <WhenBaseAttribute>(bddComponents);
            MethodInfo whenMethodInfo       = typeof(RunnerEditorBusinessLogicStaticRowsTestStaticComponent).GetMethod("WhenMethod");
            MethodInfo secondWhenMethodInfo = typeof(RunnerEditorBusinessLogicStaticRowsTestStaticComponent).GetMethod("SecondWhenMethod");

            methodBuilder.Build <WhenBaseAttribute>(bddComponents[0], whenMethodInfo).Returns <BaseMethodDescription>(baseMethodDescriptionList[0]);

            methodBuilder.Build <WhenBaseAttribute>(bddComponents[0], secondWhenMethodInfo).Returns <BaseMethodDescription>(baseMethodDescriptionList[1]);

            IMethodsFilter methodFilter = Substitute.For <IMethodsFilter>();

            methodFilter.Filter <WhenBaseAttribute>(whenMethodInfo).Returns(true);
            methodFilter.Filter <WhenBaseAttribute>(secondWhenMethodInfo).Returns(true);

            object[] constructorArguments = new object[2] {
                new BaseMethodDescriptionBuilder(), new MethodsFilterByExecutionOrder()
            };
            MethodsLoader stepMethodsLoader = Substitute.For <MethodsLoader>(constructorArguments);

            stepMethodsLoader.LoadStepMethods <WhenBaseAttribute>(bddComponents).Returns(baseMethodDescriptionList);
            RunnerEditorBusinessLogicStaticRows runnerEditorBusinessLogicStaticRows = new RunnerEditorBusinessLogicStaticRows();

            runnerEditorBusinessLogicStaticRows.DrawStaticRows <WhenBaseAttribute>(unityInterface, stepMethodsLoader, bddComponents, RunnerEditorBusinessLogicData.LabelWidthAbsolute, RunnerEditorBusinessLogicData.ButtonsWidthAbsolute);
            Received.InOrder(() =>
            {
                unityInterface.EditorGUILayoutBeginHorizontal();
                unityInterface.EditorGUIUtilityCurrentViewWidth();
                unityInterface.EditorGUILayoutLabelField("When", RunnerEditorBusinessLogicData.LabelWidthAbsolute);
                unityInterface.EditorGUILayoutLabelField("When method", 368);
                unityInterface.EditorGUILayoutEndHorizontal();

                unityInterface.EditorGUILayoutBeginHorizontal();
                unityInterface.EditorGUIUtilityCurrentViewWidth();
                unityInterface.EditorGUILayoutLabelField("and", RunnerEditorBusinessLogicData.LabelWidthAbsolute);
                unityInterface.EditorGUILayoutLabelField("Second When method", 368);
                unityInterface.EditorGUILayoutEndHorizontal();
            });
        }
        /// <summary>
        /// Draws the parameters rows.
        /// </summary>
        /// <param name="unityInterface">The unity interface.</param>
        /// <param name="foldout">If set to <c>true</c> [foldout].</param>
        /// <param name="fullMethodDescription">The full method description.</param>
        /// <param name="serializedObjects">The serialized objects.</param>
        /// <param name="lockParametersRows">If set to <c>true</c> [lock parameters rows].</param>
        public void DrawParametersRows(IUnityInterfaceWrapper unityInterface, bool foldout, FullMethodDescription fullMethodDescription, Dictionary <Type, ISerializedObjectWrapper> serializedObjects, bool lockParametersRows)
        {
            if (fullMethodDescription != null && foldout && !lockParametersRows)
            {
                ISerializedObjectWrapper serializedObject = null;
                serializedObjects.TryGetValue(fullMethodDescription.ComponentObject.GetType(), out serializedObject);

                foreach (MethodParameter parameter in fullMethodDescription.Parameters.Parameters)
                {
                    string            parameterName     = parameter.ParameterInfoObject.Name;
                    ParameterLocation parameterLocation = parameter.ParameterLocation;

                    // "given.Array.data[0]"
                    string     parameterLocationString = parameterLocation.ParameterArrayLocation.ArrayName + ".Array.data[" + parameterLocation.ParameterArrayLocation.ArrayIndex + "]";
                    GUIContent label = unityInterface.GUIContent(parameterName);
                    ISerializedPropertyWrapper property = serializedObject.FindProperty(parameterLocationString);
                    unityInterface.EditorGUILayoutPropertyField(property, label);
                }
            }

            if (fullMethodDescription != null && foldout && lockParametersRows)
            {
                float labelWidth = unityInterface.EditorGUIUtilityCurrentViewWidth();
                unityInterface.EditorGUILayoutLabelField("When there are some errors the parameters are protected to avoid data lost.", labelWidth);
            }
        }
        /// <summary>
        /// Draws the given errors.
        /// </summary>
        /// <param name="errors">The errors.</param>
        /// <param name="unityInterface">The unity interface.</param>
        /// <param name="bddExtensionRunner">The BDD extension runner.</param>
        public void Errors(List <UnityTestBDDError> errors, IUnityInterfaceWrapper unityInterface, BDDExtensionRunner bddExtensionRunner)
        {
            string openComponentButtonTextureFullPath = Utilities.GetAssetFullPath(bddExtensionRunner, this.OpenComponentButtonTextureFileName);
            string errorTextureFullPath = Utilities.GetAssetFullPath(bddExtensionRunner, this.ErrorTextureFileName);

            foreach (UnityTestBDDError error in errors)
            {
                unityInterface.EditorGUILayoutBeginHorizontal();
                unityInterface.EditorGUILayoutSeparator();
                unityInterface.EditorGUILayoutSeparator();
                unityInterface.EditorGUILayoutEndHorizontal();
                unityInterface.EditorGUILayoutBeginHorizontal();
                float currentViewWidth = unityInterface.EditorGUIUtilityCurrentViewWidth();
                if (error.ShowRedExclamationMark)
                {
                    Texture2D         errorTexture        = unityInterface.AssetDatabaseLoadAssetAtPath(errorTextureFullPath, typeof(Texture2D));
                    GUILayoutOption[] errorTextureOptions = new GUILayoutOption[2] {
                        unityInterface.GUILayoutWidth(24), unityInterface.GUILayoutHeight(24)
                    };
                    unityInterface.EditorGUILayoutLabelField(errorTexture, errorTextureOptions);
                }

                float labelWidth = currentViewWidth - 100;
                unityInterface.EditorGUILayoutLabelField(error.Message, labelWidth);

                Texture2D         openComponentButtonTexture = unityInterface.AssetDatabaseLoadAssetAtPath(openComponentButtonTextureFullPath, typeof(Texture2D));
                GUILayoutOption[] options = new GUILayoutOption[2] {
                    unityInterface.GUILayoutWidth(24), unityInterface.GUILayoutHeight(24)
                };
                if (error.ShowButton)
                {
                    if (unityInterface.GUILayoutButton(openComponentButtonTexture, EditorStyles.label, options))
                    {
                        if (error.MethodMethodInfo != null)
                        {
                            SourcesManagement.OpenMethodSourceCode(error.MethodMethodInfo, unityInterface);
                        }
                        else if (error.Component != null)
                        {
                            SourcesManagement.OpenSourceCode(error.Component, unityInterface);
                        }
                    }
                }

                unityInterface.EditorGUILayoutEndHorizontal();
            }
        }
        /// <summary>
        /// Draws the right label: "Given", "When", "Then" or "and".
        /// </summary>
        /// <typeparam name="T">The Step Method type.</typeparam>
        /// <param name="unityInterface">The unity interface.</param>
        /// <param name="index">The index.</param>
        public void DrawLabel <T>(IUnityInterfaceWrapper unityInterface, int index) where T : IGivenWhenThenDeclaration
        {
            string label = StepMethodUtilities.GetStepMethodName <T>();

            if (index > 0)
            {
                label = "and";
            }

            unityInterface.EditorGUILayoutLabelField(label, RunnerEditorBusinessLogicData.LabelWidthAbsolute);
        }
        /// <summary>
        /// Draws the static rows.
        /// </summary>
        /// <typeparam name="T">The Step Methods type.</typeparam>
        /// <param name="unityInterface">The unity interface.</param>
        /// <param name="stepMethodsLoader">The step methods loader.</param>
        /// <param name="bddComponents">The BDD components.</param>
        /// <param name="labelWidthAbsolute">The label width absolute.</param>
        /// <param name="buttonsWidthAbsolute">The buttons width absolute.</param>
        public void DrawStaticRows <T>(IUnityInterfaceWrapper unityInterface, MethodsLoader stepMethodsLoader, Component[] bddComponents, float labelWidthAbsolute, float buttonsWidthAbsolute) where T : IGivenWhenThenDeclaration
        {
            List <BaseMethodDescription> methodsList = stepMethodsLoader.LoadStepMethods <T>(bddComponents);

            for (int index = 0; index < methodsList.Count; index++)
            {
                unityInterface.EditorGUILayoutBeginHorizontal();
                float  rowWidth = unityInterface.EditorGUIUtilityCurrentViewWidth() - labelWidthAbsolute - buttonsWidthAbsolute;
                float  textSize = rowWidth - 20;
                string label    = StepMethodUtilities.GetStepMethodName <T>();
                if (index > 0)
                {
                    label = "and";
                }

                unityInterface.EditorGUILayoutLabelField(label, labelWidthAbsolute);
                string description = string.Empty;

                description = methodsList[index].Text;
                unityInterface.EditorGUILayoutLabelField(description, textSize);
                this.DrawCogButton(unityInterface, methodsList[index]);
                unityInterface.EditorGUILayoutEndHorizontal();
            }
        }
        /// <summary>
        /// Draws the Step Method sentence.
        /// </summary>
        /// <param name="unityInterface">The unity interface.</param>
        /// <param name="chosenMethod">The chosen method.</param>
        /// <param name="methodDescription">The method description.</param>
        /// <param name="textSize">Size of the text.</param>
        public void DrawDescription(IUnityInterfaceWrapper unityInterface, string chosenMethod, MethodDescription methodDescription, float textSize)
        {
            string description = string.Empty;

            if (methodDescription != null)
            {
                description = methodDescription.GetDecodifiedText();
            }
            else if (chosenMethod.Equals(string.Empty))
            {
                description = ChoseMethodFromComboBox;
            }
            else
            {
                description = "### The method " + chosenMethod + " is missing ###";
            }

            unityInterface.EditorGUILayoutLabelField(description, textSize);
        }
        public void Errors_Should_CallTheExpectedUnityEditorStatements_Given_OneErrorOnAComponent()
        {
            UnityTestBDDComponentBaseEditorBusinessLogicTestFirstDynamicComponent component = UnitTestUtility.CreateComponent <UnityTestBDDComponentBaseEditorBusinessLogicTestFirstDynamicComponent>();
            BDDExtensionRunner runner = UnitTestUtility.CreateComponent <BDDExtensionRunner>(component.gameObject);

            BaseBDDComponentEditorBusinessLogic unityTestBDDComponentBaseEditorBusinessLogic = new BaseBDDComponentEditorBusinessLogic(component);
            string expectedMessage          = "Message";
            List <UnityTestBDDError> errors = new List <UnityTestBDDError>();
            UnityTestBDDError        error  = new UnityTestBDDError();

            error.Message          = expectedMessage;
            error.Component        = component;
            error.MethodMethodInfo = null;
            errors.Add(error);

            string errorTextureFullPath = Utilities.GetAssetFullPath(runner, unityTestBDDComponentBaseEditorBusinessLogic.ErrorTextureFileName);
            string openComponentButtonTextureFullPath = Utilities.GetAssetFullPath(runner, unityTestBDDComponentBaseEditorBusinessLogic.OpenComponentButtonTextureFileName);

            IUnityInterfaceWrapper unityInterface = Substitute.For <IUnityInterfaceWrapper>();

            unityInterface.EditorGUIUtilityCurrentViewWidth().Returns(600f);
            float     labelWidth   = 500f;
            Texture2D inputTexture = new Texture2D(10, 10);

            unityInterface.AssetDatabaseLoadAssetAtPath(openComponentButtonTextureFullPath, typeof(Texture2D)).Returns(inputTexture);
            Texture2D errorTexture = new Texture2D(10, 10);

            unityInterface.AssetDatabaseLoadAssetAtPath(errorTextureFullPath, typeof(Texture2D)).Returns(errorTexture);

            GUILayoutOption buttonWidth = GUILayout.Width(16);

            unityInterface.GUILayoutWidth(24).Returns(buttonWidth);
            GUILayoutOption buttonHeight = GUILayout.Height(16);

            unityInterface.GUILayoutHeight(24).Returns(buttonHeight);
            GUILayoutOption[] options = new GUILayoutOption[2];
            options[0] = buttonWidth;
            options[1] = buttonHeight;
            unityInterface.GUILayoutButton(inputTexture, EditorStyles.label, options).Returns(false);
            GUILayoutOption[] errorTextureOptions = new GUILayoutOption[2];
            errorTextureOptions[0] = buttonWidth;
            errorTextureOptions[1] = buttonHeight;
            unityTestBDDComponentBaseEditorBusinessLogic.Errors(errors, unityInterface);

            Received.InOrder(() =>
            {
                unityInterface.EditorGUILayoutBeginHorizontal();
                unityInterface.EditorGUILayoutSeparator();
                unityInterface.EditorGUILayoutSeparator();
                unityInterface.EditorGUILayoutEndHorizontal();
                unityInterface.EditorGUILayoutBeginHorizontal();
                unityInterface.EditorGUIUtilityCurrentViewWidth();
                unityInterface.AssetDatabaseLoadAssetAtPath(errorTextureFullPath, typeof(Texture2D));
                unityInterface.GUILayoutWidth(24);
                unityInterface.GUILayoutHeight(24);
                unityInterface.EditorGUILayoutLabelField(errorTexture, Arg.Is <GUILayoutOption[]>(x => x.SequenceEqual(errorTextureOptions) == true));
                unityInterface.EditorGUILayoutLabelField(expectedMessage, labelWidth);
                unityInterface.AssetDatabaseLoadAssetAtPath(openComponentButtonTextureFullPath, typeof(Texture2D));
                unityInterface.GUILayoutWidth(24);
                unityInterface.GUILayoutHeight(24);
                unityInterface.GUILayoutButton(inputTexture, EditorStyles.label, Arg.Is <GUILayoutOption[]>(x => x.SequenceEqual(options) == true));
                unityInterface.EditorGUILayoutEndHorizontal();
            });
        }