Exemple #1
0
        private ValidationResult ValidateInternal(string[] ruleSets)
        {
            var result = new ValidationResult {
                IsValid = true
            };

            var binderPropsOrFieldsOfT = this.TypeProperties.Keys;

            foreach (var rule in ruleSets)
            {
                var strictMode = Faker.DefaultStrictMode;
                this.StrictModes.TryGetValue(rule, out strictMode);

                //If strictMode is not enabled, skip and move on to the next ruleSet.
                if (!strictMode)
                {
                    continue;
                }

                //Otherwise, we need to take a diff of what the user
                //specified and what the Binder found reflecting over
                //type T.
                this.Ignores.TryGetValue(rule, out HashSet <string> ignores);

                this.Actions.TryGetValue(rule, out var populateActions);

                var userSet = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                if (ignores != null)
                {
                    userSet.UnionWith(ignores);
                }
                if (populateActions != null)
                {
                    userSet.UnionWith(populateActions.Keys);
                }

                //Get the set properties or fields that are only
                //known to the binder, while removing
                //items in userSet that are known to both the user and binder.

                userSet.SymmetricExceptWith(binderPropsOrFieldsOfT);

                //What's left in userSet is the set of properties or fields
                //that the user does not know about + .Rule() methods.

                if (userSet.Count > 0)
                {
                    foreach (var propOrFieldOfT in userSet)
                    {
                        if (populateActions.TryGetValue(propOrFieldOfT, out var populateAction))
                        {   // Very much a .Rules() action
                            if (populateAction.ProhibtInStrictMode)
                            {
                                result.ExtraMessages.Add(
                                    $"When StrictMode is set to True the Faker<{typeof(T).Name}>.Rules(...) method cannot verify that all properties have rules. You need to use Faker<{typeof(T).Name}>.RuleFor( x => x.Prop, ...) for each property to ensure each property has an associated rule when StrictMode is true; otherwise, set StrictMode to False in order to use Faker<{typeof(T).Name}>.Rules() method.");
                                result.IsValid = false;
                            }
                        }
                        else //The user doesn't know about this property or field. Log it as a validation error.
                        {
                            result.MissingRules.Add(propOrFieldOfT);
                            result.IsValid = false;
                        }
                    }
                }
            }
            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Given an instance of T, populate it with the desired rule sets.
        /// </summary>
        protected virtual void PopulateInternal(T instance, string[] ruleSets)
        {
            ValidationResult vr = null;

            if (!IsValid.HasValue)
            {
                //run validation
                vr           = ValidateInternal(ruleSets);
                this.IsValid = vr.IsValid;
            }
            if (!IsValid.GetValueOrDefault())
            {
                throw MakeValidationException(vr ?? ValidateInternal(ruleSets));
            }

            var typeProps = TypeProperties;

            lock (Randomizer.Locker.Value)
            {
                //Issue 57 - Make sure you generate a new context
                //           before executing any rules.
                //Issue 143 - If the FakerHub doesn't have any context
                //            (eg NewContext() has never been called), then call it
                //            so we can increment IndexGlobal and IndexFaker.
                if (!this.FakerHub.HasContext)
                {
                    FakerHub.NewContext();
                }

                foreach (var ruleSet in ruleSets)
                {
                    if (this.Actions.TryGetValue(ruleSet, out var populateActions))
                    {
                        foreach (var action in populateActions.Values)
                        {
                            typeProps.TryGetValue(action.PropertyName, out MemberInfo member);
                            var valueFactory = action.Action;
                            if (valueFactory is null)
                            {
                                continue;                 // An .Ignore() rule.
                            }
                            if (member != null)
                            {
                                var prop = member as PropertyInfo;
                                prop?.SetValue(instance, valueFactory(FakerHub, instance), null);

                                var field = member as FieldInfo;
                                field?.SetValue(instance, valueFactory(FakerHub, instance));
                            }
                            else // member would be null if this was an RuleForObject.
                            {
                                //Invoke this if this is a basic rule which does not select a property or a field.
                                var outputValue = valueFactory(FakerHub, instance);
                            }
                        }
                    }
                }

                foreach (var ruleSet in ruleSets)
                {
                    if (this.FinalizeActions.TryGetValue(ruleSet, out FinalizeAction <T> finalizer))
                    {
                        finalizer.Action(this.FakerHub, instance);
                    }
                }
            }
        }