public void LoopWithinLoop_bug_17651() { using (new WorkflowRunContext { RunTriggersInCurrentThread = true }) { var wf = new Workflow() { Name = "LoopWithinLoop_bug_17651" }; wf.AddDefaultExitPoint(); var count = new IntegerArgument() { Name = "count" }; ActivityTestHelper.AddVariableToWorkflow(wf, count.As <ActivityArgument>()); wf.AddExpressionToWorkflowVariable("count", "0"); var foreachX = new ForEachResource() { Name = "ForEachX" + DateTime.Now }; var foreachXAs = foreachX.As <WfActivity>(); ActivityTestHelper.AddExpressionToActivityArgument(wf, foreachXAs, "List", "all([Workflow Event])"); wf.FirstActivity = foreachXAs; wf.ContainedActivities.Add(foreachXAs); var foreachY = new ForEachResource() { Name = "ForEachY" + DateTime.Now }; var foreachYAs = foreachY.As <WfActivity>(); ActivityTestHelper.AddExpressionToActivityArgument(wf, foreachYAs, "List", "all([Event Email Priority Enum])"); wf.ContainedActivities.Add(foreachYAs); ActivityTestHelper.AddTransition(wf, foreachXAs, foreachYAs, "Loop"); ActivityTestHelper.AddTermination(wf, foreachXAs, "Finished"); var assign = new AssignToVariable() { Name = "Assign" }; var assignAs = assign.As <WfActivity>(); assign.TargetVariable = count.As <ActivityArgument>(); ActivityTestHelper.AddExpressionToActivityArgument(wf, assignAs, "Value", "count + 1"); wf.ContainedActivities.Add(assignAs); ActivityTestHelper.AddTransition(wf, foreachYAs, assignAs, "Loop"); ActivityTestHelper.AddTransition(wf, foreachYAs, foreachXAs, "Finished"); ActivityTestHelper.AddTransition(wf, assignAs, foreachYAs); var output = new IntegerArgument() { Name = "out" }; var outputAs = output.As <ActivityArgument>(); wf.OutputArguments.Add(outputAs); ActivityTestHelper.AddAssignToVar(wf, "Set Output", "count", "out"); ActivityTestHelper.AddMissingExpressionParametersToWorkflow(wf); wf.Save(); ToDelete.Add(wf.Id); var run = (RunWorkflow(wf)); var outputs = run.GetOutput(); Assert.AreEqual(1, outputs.Count, "There is one output argument"); var result = (int)outputs["out"]; var triggeredOnCount = Entity.GetInstancesOfType <WorkflowEventEnum>(false).Count(); var runStateCount = Entity.GetInstancesOfType <EventEmailPriorityEnum>(false).Count(); Assert.AreEqual(triggeredOnCount * runStateCount, result, "The nested loops ran the correct number of times."); } }
public void SimpleCountingLoop( ) { using (new WorkflowRunContext { RunTriggersInCurrentThread = true }) { var wf = new Workflow() { Name = "Simple Counting " + DateTime.Now }; wf.AddDefaultExitPoint(); var input = new ResourceListArgument { Name = "in" }; wf.InputArguments.Add(input.As <ActivityArgument>()); var output = new IntegerArgument { Name = "out" }; wf.OutputArguments.Add(output.As <ActivityArgument>()); var employeeType = Entity.Get <EntityType>(new EntityRef("test", "employee")); wf.AddVariable <IntegerArgument>("Count") .AddAssignToVar("Assign To Count", "0", "Count") .AddForEach("foreach1", "in", "test:employee") .AddAssignToVar("Assign To Count 2", "[Count] + 1", "Count", "foreach1", "Loop") .AddTransition("Assign To Count 2", "foreach1"); ActivityTestHelper.AddAssignToVar(wf, "AssignOutput", "Count", "out"); ActivityTestHelper.AddMissingExpressionParametersToWorkflow(wf); wf.Save(); var createdCount = 15; var resources = Enumerable.Range(0, createdCount).Select(v => new Person() { Name = v.ToString() }).ToList(); Entity.Save(resources); var wfInput = new Dictionary <string, object> { { "in", resources } }; var run = (RunWorkflow(wf, wfInput)); IDictionary <string, object> outputs = run.GetOutput(); Assert.AreEqual(1, outputs.Count, "There is one output argument"); var result = (int)outputs["out"]; Assert.AreEqual(createdCount, result, "The loop ran the correct number of times"); } }
/// <summary>Given an arg inst and a value create and activityArgument ready for storage.</summary> /// <param name="activity">The <see cref="WfActivity"/> being run. This cannot be null.</param> /// <param name="arg">The argument for the activity. This cannot be null.</param> /// <param name="value">The value of the argument. Its type is determined by <paramref name="arg"/>. This may be null for certain argument types.</param> /// <returns>The converted value.</returns> /// <exception cref="ArgumentNullException">Neither <paramref name="activity"/> nor <paramref name="arg"/> can be null.</exception> /// <exception cref="ArgumentException"><paramref name="arg"/> must be of a supported type.</exception> public static ActivityArgument ConvertArgInstValue(WfActivity activity, ActivityArgument arg, object value) { if (activity == null) { throw new ArgumentNullException(nameof(activity)); } if (arg == null) { throw new ArgumentNullException(nameof(arg)); } ActivityArgument result; string name = $"{activity.Name ?? "[Unnamed]"}.{arg.Name ?? "[Unnamed]"}"; if (arg.Is <ResourceListArgument>()) { var list = (IEnumerable <IEntity>)value; var created = new ResourceListArgument { Name = name }; if (list != null) { var cleanList = list.Where(e => e != null).Select(e => e.As <Resource>()); created.ResourceListParameterValues.AddRange(cleanList); } result = created.As <ActivityArgument>(); } else if (arg.Is <ResourceArgument>()) { var res = (IEntity)value; var created = new ResourceArgument { Name = name, ResourceParameterValue = res?.As <Resource>() }; result = created.As <ActivityArgument>(); } else if (arg.Is <StringArgument>()) { var created = new StringArgument { Name = name, StringParameterValue = (string)value }; result = created.As <ActivityArgument>(); } else if (arg.Is <BoolArgument>()) { var created = new BoolArgument { Name = name, BoolParameterValue = (bool?)value ?? false }; result = created.As <ActivityArgument>(); } else if (arg.Is <IntegerArgument>()) { var created = new IntegerArgument { Name = name, IntParameterValue = (int?)value ?? 0 }; result = created.As <ActivityArgument>(); } else if (arg.Is <DecimalArgument>()) { var created = new DecimalArgument { Name = name, DecimalParameterValue = (decimal?)value ?? 0 }; result = created.As <ActivityArgument>(); } else if (arg.Is <CurrencyArgument>()) { var created = new CurrencyArgument { Name = name, DecimalParameterValue = (decimal?)value ?? 0 }; result = created.As <ActivityArgument>(); } else if (arg.Is <DateTimeArgument>()) { var created = new DateTimeArgument { Name = name, DateTimeParameterValue = (DateTime?)value }; result = created.As <ActivityArgument>(); } else if (arg.Is <DateArgument>()) { var created = new DateArgument { Name = name, DateParameterValue = (DateTime?)value }; result = created.As <ActivityArgument>(); } else if (arg.Is <TimeArgument>()) { // ensure that timeparametervalue only ever holds a datetime var dt = value is TimeSpan?TimeType.NewTime((TimeSpan)value) : (DateTime?)value; var created = new TimeArgument { Name = name, TimeParameterValue = dt }; result = created.As <ActivityArgument>(); } else if (arg.Is <GuidArgument>()) { var created = new GuidArgument { Name = name, GuidParameterValue = (Guid?)value ?? Guid.Empty }; result = created.As <ActivityArgument>(); } else { throw new ArgumentException($"Unsupported ActivityArgument '{arg.IsOfType.First().Name}' in '{name}'", "arg"); } return(result); }