Example #1
0
        /// <summary>
        ///     Returns list or errors
        /// </summary>
        /// <param name="view">View object</param>
        /// <returns>List of error descriptions (empty list if no contracts are violated)</returns>
        private static IEnumerable <ApiErrorView> PerformSpecificChecks(object view)
        {
            var result      = new List <ApiErrorView>();
            var methodInfos = view
                              .GetType()
                              .GetRuntimeMethods()
                              .Where(
                mi =>
                mi.ReturnType == typeof(bool) &&
                mi.GetParameters().Length == 0 &&
                mi.GetCustomAttributes <ApiViewCheckAttribute>().Any())
                              .ToList();

            foreach (var methodInfo in methodInfos)
            {
                var deleg       = methodInfo.CreateDelegate(typeof(Func <bool>), view);
                var checkResult = (bool)deleg.DynamicInvoke();
                if (!checkResult)
                {
                    var apiErrorView = ApiErrorViewFactory.ViewContractViolation(view,
                                                                                 methodInfo.GetCustomAttribute <ApiViewCheckAttribute>().CheckDescription);
                    result.Add(apiErrorView);
                }
            }
            return(result);
        }
Example #2
0
        private static void PerformTest()
        {
            var viewTree = new NodeView
            {
                Name     = "Root",
                Children = new List <NodeView>
                {
                    new NodeView
                    {
                        Children = new List <NodeView>
                        {
                            new NodeView()
                        }
                    }
                },
                IsLeaf = true
            };

            var checkResult = viewTree.CheckAsView();
            var logBuilder  = new StringBuilder();

            logBuilder.AppendLine();
            logBuilder.AppendLine($"IsCorrect: {checkResult.IsCorrect}");
            logBuilder.AppendLine(Separator);
            logBuilder.AppendLine("Message:");
            logBuilder.AppendLine(checkResult.ErrorDescription);

            var level = checkResult.IsCorrect ? LogLevel.Info : LogLevel.Warning;

            LogMessage(level, logBuilder.ToString());

            var apiErrorView = ApiErrorViewFactory.ForeignKeyError(typeof(List <string>), "jljfslkdf");

            using (var stringWriter = new StringWriter())
            {
                var settings = new XmlWriterSettings
                {
                    Indent = true,
                    NewLineOnAttributes = true
                };
                using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
                {
                    var xmlSerializer = new XmlSerializer(apiErrorView.GetType());
                    xmlSerializer.Serialize(xmlWriter, apiErrorView);
                }
                LogMessage(LogLevel.Info, stringWriter.ToString());

                LogMessage(LogLevel.Info, EnumInfoProvider.GetEnumElementByName("1", typeof(SimpleEnum)).ToString());
                var str = EnumInfoProvider.GetElementName(FlagsEnum.Second | FlagsEnum.Third);
                LogMessage(LogLevel.Info, EnumInfoProvider.GetEnumElementByName <FlagsEnum>(str).ToString());
            }
        }
Example #3
0
        private static ViewCheckResult BuildCheckResult(object view, List <ApiErrorView> errors, List <ApiErrorView> innerErrors)
        {
            var hasErrors      = errors.Any();
            var hasInnerErrors = innerErrors.Any();

            if (!hasInnerErrors && !hasErrors)
            {
                return(ViewCheckResult.Ok());
            }

            var allErrors = new List <ApiErrorView>(errors);

            if (hasInnerErrors)
            {
                allErrors.Add(ApiErrorViewFactory.InnerErrors(view, innerErrors));
            }

            return(ViewCheckResult.Error(ApiErrorViewFactory.InnerErrors(view, allErrors)));
        }
Example #4
0
        public static ViewCheckResult CheckAsView(this object view)
        {
            var type = view.GetType();
            var list = view as IList;

            if (list != null && type.IsConstructedGenericType)
            {
                var checkResults = (from object item in list select CheckAsView(item)).ToList();
                if (!checkResults.Any())
                {
                    return(ViewCheckResult.Ok());
                }

                var errorViews = checkResults
                                 .Where(result => !result.IsCorrect)
                                 .Select(result => result.ApiErrorView)
                                 .ToList();

                return(ViewCheckResult.Error(ApiErrorViewFactory.InnerErrors(view, errorViews)));
            }
            return(ViewChecker.CheckContract(view));
        }
Example #5
0
        /// <summary>
        ///     Checks if view complies with it's contract
        /// </summary>
        /// <param name="view">Object to check</param>
        /// <returns>Simply ok or verbose contract errors description (for reading, not serializing)</returns>
        /// <exception cref="InvalidOperationException">
        ///     Will be thrown if <see cref="view"/> does not have <see cref="ApiViewAttribute"/> attribute
        /// </exception>
        public static ViewCheckResult CheckContract(object view)
        {
            if (view == null)
            {
                return(ViewCheckResult.Ok());
            }

            if (!view.IsApiView())
            {
                throw new InvalidOperationException("No classes except API views can have contracts");
            }

            try
            {
                var properties        = view.GetType().GetRuntimeProperties();
                var checkResults      = new List <ApiErrorView>();
                var innerCheckResults = new List <ApiErrorView>();

                checkResults.AddRange(PerformSpecificChecks(view));

                foreach (var propertyInfo in properties)
                {
                    var propertyValue = propertyInfo.GetValue(view);

                    if (propertyValue != null)
                    {
                        if (propertyValue.IsApiView())
                        {
                            var checkResult = CheckContract(propertyValue);
                            if (!checkResult.IsCorrect)
                            {
                                innerCheckResults.Add(checkResult.ApiErrorView);
                            }
                        }
                        if (propertyValue.IsApiViewList())
                        {
                            var list = propertyValue as IList;
                            if (list == null)
                            {
                                continue;
                            }
                            innerCheckResults.AddRange(from object item in list
                                                       select CheckContract(item)
                                                       into checkResult
                                                       where !checkResult.IsCorrect
                                                       select checkResult.ApiErrorView);
                        }
                    }

                    var contractAttributes = propertyInfo.GetCustomAttributes <ApiContractAttribute>().ToList();
                    if (!contractAttributes.Any())
                    {
                        continue;
                    }

                    if (contractAttributes.Count != 1)
                    {
                        return(ViewCheckResult.Error(ApiErrorViewFactory.Unspecified()));
                    }

                    var contractAttribute = contractAttributes[0];
                    var contractType      = contractAttribute.Type;

                    var failedChecks = CheckerDictionary
                                       .Where(kv => contractType.HasFlag(kv.Key) && !kv.Value.Invoke(propertyValue))
                                       .Select(kv => kv.Key)
                                       .ToList();

                    if (failedChecks.Any())
                    {
                        var propertyName = propertyInfo.Name;
                        checkResults.AddRange(
                            failedChecks.Select(fc => ApiErrorViewFactory.ViewPropertyContractViolation(view, propertyName, fc)));
                    }
                }
                return(BuildCheckResult(view, checkResults, innerCheckResults));
            }
            catch (Exception ex)
            {
                return(ViewCheckResult.Error(ApiErrorViewFactory.Unspecified($"Failed to check view: {ex.Message}")));
            }
        }