< Summary

Information
Class: Elsa.Workflows.Activities.SwitchCase
Assembly: Elsa.Workflows.Core
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Activities/Switch.cs
Line coverage
44%
Covered lines: 8
Uncovered lines: 10
Coverable lines: 18
Total lines: 158
Line coverage: 44.4%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%210%
.ctor(...)100%11100%
.ctor(...)100%210%
.ctor(...)100%210%
.ctor(...)100%210%
.ctor(...)100%210%
get_Label()100%11100%
get_Condition()100%11100%
get_Activity()100%11100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Activities/Switch.cs

#LineLine coverage
 1using System.Runtime.CompilerServices;
 2using System.Text.Json.Serialization;
 3using Elsa.Expressions.Contracts;
 4using Elsa.Expressions.Models;
 5using Elsa.Workflows.Attributes;
 6using Elsa.Workflows.Models;
 7using Elsa.Workflows.UIHints;
 8using JetBrains.Annotations;
 9
 10namespace Elsa.Workflows.Activities;
 11
 12/// <summary>
 13/// The Switch activity is an approximation of the `switch` construct in C#.
 14/// When a case evaluates to true, the associated activity is then scheduled for execution.
 15/// </summary>
 16[Activity("Elsa", "Branching", "Evaluate a set of case conditions and schedule the activity for a matching case.")]
 17[PublicAPI]
 18public class Switch : Activity
 19{
 20    /// <inheritdoc />
 21    public Switch([CallerFilePath] string? source = null, [CallerLineNumber] int? line = null) : base(source, line)
 22    {
 23    }
 24
 25    /// <summary>
 26    /// The value to switch on, made available as output for capturing.
 27    /// </summary>
 28    public Output<object>? Output { get; set; }
 29
 30    /// <summary>
 31    /// The cases to evaluate.
 32    /// </summary>
 33    [Input(
 34        Description = "The cases to evaluate.",
 35        UIHint = "switch-editor"
 36    )]
 37    public ICollection<SwitchCase> Cases { get; set; } = new List<SwitchCase>();
 38
 39    /// <summary>
 40    /// The switch mode determines whether the first match should be scheduled, or all matches.
 41    /// </summary>
 42    [Input(
 43        Description = "The switch mode determines whether the first match should be scheduled, or all matches.",
 44        UIHint = InputUIHints.DropDown
 45    )]
 46    public Input<SwitchMode> Mode { get; set; } = new(SwitchMode.MatchFirst);
 47
 48    /// <summary>
 49    /// The default activity to schedule when no case matches.
 50    /// </summary>
 51    [Port] public IActivity? Default { get; set; }
 52
 53    /// <inheritdoc />
 54    protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
 55    {
 56        var matchingCases = (await FindMatchingCasesAsync(context.ExpressionExecutionContext)).ToList();
 57        var hasAnyMatches = matchingCases.Any();
 58        var mode = context.Get(Mode);
 59        var results = mode == SwitchMode.MatchFirst ? hasAnyMatches ? new[] { matchingCases.First() } : Array.Empty<Swit
 60
 61        if (hasAnyMatches)
 62        {
 63            foreach (var result in results)
 64            {
 65                await context.ScheduleActivityAsync(result.Activity, OnChildActivityCompletedAsync);
 66            }
 67
 68            return;
 69        }
 70
 71        await context.ScheduleActivityAsync(Default, OnChildActivityCompletedAsync);
 72    }
 73
 74    private async Task<IEnumerable<SwitchCase>> FindMatchingCasesAsync(ExpressionExecutionContext context)
 75    {
 76        var matchingCases = new List<SwitchCase>();
 77        var expressionEvaluator = context.GetRequiredService<IExpressionEvaluator>();
 78
 79        foreach (var switchCase in Cases)
 80        {
 81            var result = await expressionEvaluator.EvaluateAsync<bool?>(switchCase.Condition, context);
 82
 83            if (result == true)
 84            {
 85                matchingCases.Add(switchCase);
 86            }
 87        }
 88
 89        return matchingCases;
 90    }
 91
 92    private async ValueTask OnChildActivityCompletedAsync(ActivityCompletedContext context)
 93    {
 94        await context.TargetContext.CompleteActivityAsync();
 95    }
 96}
 97
 98/// <summary>
 99/// Represents an individual case of the <see cref="Switch"/> activity.
 100/// </summary>
 101public class SwitchCase
 102{
 103    /// <summary>
 104    /// Initializes a new instance of the <see cref="SwitchCase"/> class.
 105    /// </summary>
 106    [JsonConstructor]
 0107    public SwitchCase()
 108    {
 0109    }
 110
 111    /// <summary>
 112    /// Initializes a new instance of the <see cref="SwitchCase"/> class.
 113    /// </summary>
 114    /// <param name="label">The label of the case.</param>
 115    /// <param name="condition">The condition to evaluate.</param>
 116    /// <param name="activity">The activity to schedule when the condition evaluates to true.</param>
 15117    public SwitchCase(string label, Expression condition, IActivity activity)
 118    {
 15119        Label = label;
 15120        Condition = condition;
 15121        Activity = activity;
 15122    }
 123
 124    /// <inheritdoc />
 0125    public SwitchCase(string label, Func<ExpressionExecutionContext, ValueTask<bool>> condition, IActivity activity) : t
 126    {
 0127    }
 128
 129    /// <inheritdoc />
 0130    public SwitchCase(string label, Func<ValueTask<bool>> condition, IActivity activity) : this(label, Expression.Delega
 131    {
 0132    }
 133
 134    /// <inheritdoc />
 0135    public SwitchCase(string label, Func<ExpressionExecutionContext, bool> condition, IActivity activity) : this(label, 
 136    {
 0137    }
 138
 139    /// <inheritdoc />
 0140    public SwitchCase(string label, Func<bool> condition, IActivity activity) : this(label, Expression.DelegateExpressio
 141    {
 0142    }
 143
 144    /// <summary>
 145    /// The label of the case.
 146    /// </summary>
 29147    public string Label { get; set; } = null!;
 148
 149    /// <summary>
 150    /// The condition to evaluate.
 151    /// </summary>
 44152    public Expression Condition { get; set; } = Expression.LiteralExpression(false);
 153
 154    /// <summary>
 155    /// The activity to schedule when the condition evaluates to true.
 156    /// </summary>
 47157    public IActivity? Activity { get; set; }
 158}