Пример #1
0
        /// <summary>
        /// Runs the specified action for all combinations of the specified combinatorial engine.
        /// </summary>
        /// <param name="engine">The engine to use.</param>
        /// <param name="action">Action to call for each combination.</param>
        /// <param name="skipTo">If specified determines which combination to skip to. Must be null when running outside the debugger.</param>
        public static void RunCombinations(this ICombinatorialEngine engine, Action <Dictionary <string, object> > action, int?skipTo = null)
        {
            if (skipTo.HasValue && !Debugger.IsAttached)
            {
                throw new ArgumentException("The skipTo parameter was used in RunCombinations and the code is not running under debugger. " +
                                            "The skipTo is only intended for usage during debugging and MUST NOT be present in checked-in code.");
            }

            int combinationNumber = 0;

            while (engine.NextCombination())
            {
                combinationNumber++;
                if (skipTo.HasValue && skipTo > combinationNumber)
                {
                    continue;
                }

                try
                {
                    engine.LogCombinationNumber(combinationNumber);
                    action(engine.CurrentDimensionValues);
                }
                catch (Exception e)
                {
                    string message = string.Format(
                        "Failure in combination #{1} for dimension values:{0}{2}{0}",
                        Environment.NewLine,
                        combinationNumber.ToString(),
                        engine.DescribeDimensions());
                    throw new Exception(message, e);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Writes the current dimensions and their values of the specified engine to a string for logging purposes.
        /// </summary>
        /// <param name="engine">The combinatorial engine to write values for.</param>
        /// <returns>String representation suitable for logging.</returns>
        public static string DescribeDimensions(this ICombinatorialEngine engine)
        {
            if (engine.CurrentDimensionValues == null)
            {
                return("[none]");
            }

            StringBuilder sb    = new StringBuilder();
            bool          first = true;

            foreach (var dimension in engine.Dimensions)
            {
                if (!first)
                {
                    sb.AppendLine();
                }

                first = false;
                sb.Append(dimension.Name);
                sb.Append(": [");
                object dimensionValue = engine.CurrentDimensionValues[dimension.Name];
                if (dimensionValue == null)
                {
                    dimensionValue = "*null*";
                }
                else if (dimensionValue is string[])
                {
                    dimensionValue = "string[]:" + string.Join(",", (string[])dimensionValue);
                }
                sb.Append(dimensionValue);
                sb.Append("]");
            }

            return(sb.ToString());
        }
Пример #3
0
        /// <summary>
        /// Runs combinations using specified engine provider.
        /// </summary>
        /// <param name="provider">The engine provider to use to create the combinatorial engine.</param>
        /// <param name="action">The action to run for each combination.</param>
        /// <param name="skipTo">If specified determines which combination to skip to. Must be null when running outside the debugger.</param>
        /// <param name="dimensions">Array of enumerations which represent the dimensions, these are matched by order to the parameters of the action.</param>
        public static void RunCombinations(this ICombinatorialEngineProvider provider, Delegate action, int?skipTo, params IEnumerable[] dimensions)
        {
            ParameterInfo[]          parameters         = action.Method.GetParameters();
            CombinatorialDimension[] dimensionInstances = dimensions.Select((dimensionEnumerable, dimensionIndex) =>
                                                                            new CombinatorialDimension(parameters[dimensionIndex].Name, dimensionEnumerable)).ToArray();

            ICombinatorialEngine engine = provider.CreateEngine(dimensionInstances);

            engine.RunCombinations((dimensionValues) =>
            {
                action.DynamicInvoke(parameters.Select(parameter => dimensionValues[parameter.Name]).ToArray());
            }, skipTo);
        }