Пример #1
0
        public virtual object                       Clone()
        {
            ModelParameter clone = (ModelParameter)this.MemberwiseClone();

            //Clone the collections, so add/remove is independent
            clone.Values = (ModelValues)this.Values.Clone();
            return(clone);
        }
Пример #2
0
        protected ModelParameters               DetermineParameters(ModelAction action)
        {
            try
            {
                ModelParameters allparameters = action.Parameters;
                ModelParameters choosen       = new ModelParameters();

                //Loop through the method parameters
                foreach (ParameterInfo info in action.Method.GetParameters())
                {
                    //Find the all parameters assoicated with this param
                    ModelParameters parameters = allparameters.Find(info.Name);
                    //Exclude invalid parameters (if not requested)
                    if (!this.InvalidParameters)
                    {
                        parameters = (ModelParameters)parameters.FindFlag((int)ModelItemFlags.Throws, false);
                    }
                    if (parameters.Count <= 0)
                    {
                        throw new ModelException(this, "Unable to find a ModelParameter for method parameter: '" + info.Name + "'");
                    }

                    //Choose one of the parameters, based upon weight
                    ModelParameter parameter = parameters.Choose(this);
                    parameter.Accessed++;

                    //Note: We cloning the param, since were choosing only one of the values to use this time.
                    parameter = (ModelParameter)parameter.Clone();

                    //Choose (or generate) one of the values
                    ModelValue value = DetermineParameterValue(parameter);
                    value.Accessed++;

                    //Add it to the array
                    parameter.Value = value;
                    choosen.Add(parameter);
                }

                return(choosen);
            }
            catch (Exception e)
            {
                //Make this easier to debug
                throw new ModelException(this, "DetermineParameters", e);
            }
        }
Пример #3
0
        protected ModelValue                    DetermineParameterValue(ModelParameter parameter)
        {
            ModelValues values = new ModelValues();

            values.Add(parameter.Values);

            //Parameter values, can be specified in numerous ways:
            //	1.  Value list - simply choose one of them
            //	2.  Expression - generate value that meets the criteria (ie: <, >, !=, etc)
            //	3.  Variable - simply obtain the value by calling a method/field

            //#3. Variable - simply obtain the value by calling a method/field
            if (parameter.Variable != null)
            {
                object current = parameter.Variable.CachedValue;
                if (current is IEnumerable && !typeof(IEnumerable).IsAssignableFrom(parameter.Type))
                {
                    foreach (object v in (IEnumerable)current)
                    {
                        values.Add(new ModelValue(v));
                    }
                }
                else
                {
                    values.Add(new ModelValue(current));
                }
            }

            //First ensure we have a set of values/requirements to choose from
            if (values.Count <= 0)
            {
                throw new ModelException(parameter, "No values specified to choose from");
            }

            //Note: Since we allow the operator on the individual values, this is a little more complex.
            //Note: We allow multiple operators, not just one, (ie: x > 5, < 10, and != 7).
            //This gives you great power and flexibility in expressions, but means we have to work a
            //little hard in determing a value that meets the requirements

            //#1.  Value list - simply choose one of them
            //Note: Bitmask is already exploded into combinations
            ModelValues equalvalues = values.FindOperator(ModelValueOperator.Equal);

            //#2.  Expression - generate value that meets the criteria (ie: <, >, !=, etc)
            //Note: Since we allow the operator on the individual values, this is a little more complex.
            //Note: We allow multiple operators, not just one, (ie: x > 5, < 10, and != 7).
            //This gives you great power and flexibility in expressions, but means we have to work a
            //little hard in determing a value that meets the requirements.
            int min = Int32.MinValue;
            int max = Int32.MaxValue;

            //Adjust our parameter, simplier to loop over all of them
            foreach (ModelValue value in values.FindOperator(ModelValueOperator.Equal, false).FindOperator(ModelValueOperator.NotEqual, false))
            {
                //To keep this simple, we just support integers (for now).
                if (!(value.Value is int || value.Value is Nullable <int>))
                {
                    throw new ModelException(parameter, "Generated value range must be specified in terms of integers, not '" + value.Type + "'");
                }

                //Simplify our life
                int v = (int)value.Value;

                //Adjust Max (if there is one)
                switch (value.Operator)
                {
                case ModelValueOperator.LessThanOrEqual:
                    if (v < max)
                    {
                        max = v;
                    }
                    break;

                case ModelValueOperator.GreaterThanOrEqual:
                    if (v > min)
                    {
                        min = v;
                    }
                    break;

                case ModelValueOperator.LessThan:
                    if (v - 1 < max && v > Int32.MinValue /*prevent underflow*/)
                    {
                        max = v - 1;
                    }
                    break;

                case ModelValueOperator.GreaterThan:
                    if (v + 1 > min && v < Int32.MaxValue /*prevent overflow*/)
                    {
                        min = v + 1;
                    }
                    break;
                }
                ;
            }

            //Choose a new value, within the specified range
            //Note: We retry in case it equals one of the existing invalid values (ie: !=)
            while (true)
            {
                ModelValue choice = null;
                if (equalvalues.Count > 0)
                {
                    //Simple: Choose one of the specified values
                    choice = new ModelValue(equalvalues.Choose(this).Value);
                }
                else
                {
                    //Otherwise: Choose a value within in the range
                    //Note: Random.Next = min <= x < max (so we have to add one)
                    int index = _options.Random.Next(min, max < Int32.MaxValue ? max + 1 : max);                        //Prevent overflow
                    choice = new ModelValue(index);
                }

                //As soon as we find a value, within the range, (and not in the invalid list), were done
                bool valid = true;
                foreach (ModelValue invalid in values.FindOperator(ModelValueOperator.NotEqual))
                {
                    if (invalid.Evaluate(choice.Value, ModelValueOperator.Equal))
                    {
                        valid = false;
                    }
                }

                if (valid)
                {
                    return(choice);
                }
            }
        }