From e1784f7f6c1a444d5e14ab7f6f2d734596c39805 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 31 Jul 2023 20:03:41 +0200 Subject: [PATCH] Rename GetVariableByName to GetVariable and increase XML coverage --- .../Elsa.Expressions/Contracts/IExpression.cs | 3 ++ .../Contracts/IExpressionHandler.cs | 10 +++++ .../Contracts/IExpressionHandlerRegistry.cs | 18 +++++++- .../Models/ExpressionSyntaxDescriptor.cs | 45 +++++++++++++++++++ .../Elsa.Expressions/Models/Literal.cs | 22 +++++++++ .../Services/ExpressionHandlerRegistry.cs | 6 +-- .../ActivityExecutionContextExtensions.cs | 2 +- .../ExpressionExecutionContextExtensions.cs | 10 ++--- .../Scenarios/SetGetVariables/Workflows.cs | 4 +- ...pressionExecutionContextExtensionsTests.cs | 12 ++--- 10 files changed, 113 insertions(+), 19 deletions(-) diff --git a/src/modules/Elsa.Expressions/Contracts/IExpression.cs b/src/modules/Elsa.Expressions/Contracts/IExpression.cs index 9ec5f94da..5b680e892 100644 --- a/src/modules/Elsa.Expressions/Contracts/IExpression.cs +++ b/src/modules/Elsa.Expressions/Contracts/IExpression.cs @@ -1,5 +1,8 @@ namespace Elsa.Expressions.Contracts; +/// +/// Marker interface for expression types. +/// public interface IExpression { } \ No newline at end of file diff --git a/src/modules/Elsa.Expressions/Contracts/IExpressionHandler.cs b/src/modules/Elsa.Expressions/Contracts/IExpressionHandler.cs index 97024e5bb..57015948c 100644 --- a/src/modules/Elsa.Expressions/Contracts/IExpressionHandler.cs +++ b/src/modules/Elsa.Expressions/Contracts/IExpressionHandler.cs @@ -2,7 +2,17 @@ using Elsa.Expressions.Models; namespace Elsa.Expressions.Contracts; +/// +/// Evaluates an expression. +/// public interface IExpressionHandler { + /// + /// Evaluates an expression. + /// + /// The expression to evaluate. + /// The expected return type. + /// The context in which the expression is evaluated. + /// The result of the evaluation. ValueTask EvaluateAsync(IExpression expression, Type returnType, ExpressionExecutionContext context); } \ No newline at end of file diff --git a/src/modules/Elsa.Expressions/Contracts/IExpressionHandlerRegistry.cs b/src/modules/Elsa.Expressions/Contracts/IExpressionHandlerRegistry.cs index 18220d7c5..afd5dd508 100644 --- a/src/modules/Elsa.Expressions/Contracts/IExpressionHandlerRegistry.cs +++ b/src/modules/Elsa.Expressions/Contracts/IExpressionHandlerRegistry.cs @@ -1,7 +1,21 @@ namespace Elsa.Expressions.Contracts; +/// +/// A registry of expression handlers. +/// public interface IExpressionHandlerRegistry { - void Register(Type expression, Type handler); - IExpressionHandler? GetHandler(IExpression input); + /// + /// Registers an expression handler for the specified expression type. + /// + /// The expression type. + /// The expression handler type. + void Register(Type expressionType, Type handler); + + /// + /// Returns an expression handler for the specified expression. + /// + /// The expression. + /// An expression handler or null if no handler was found. + IExpressionHandler? GetHandler(IExpression expression); } \ No newline at end of file diff --git a/src/modules/Elsa.Expressions/Models/ExpressionSyntaxDescriptor.cs b/src/modules/Elsa.Expressions/Models/ExpressionSyntaxDescriptor.cs index 9d975acd1..5774aa182 100644 --- a/src/modules/Elsa.Expressions/Models/ExpressionSyntaxDescriptor.cs +++ b/src/modules/Elsa.Expressions/Models/ExpressionSyntaxDescriptor.cs @@ -3,23 +3,68 @@ using Elsa.Expressions.Contracts; namespace Elsa.Expressions.Models; +/// +/// Describes an expression syntax. +/// public class ExpressionSyntaxDescriptor { + /// + /// Gets or sets the syntax name. + /// public string Syntax { get; init; } = default!; + + /// + /// Gets or sets the expression type. + /// public Type Type { get; init; } = default!; + + /// + /// Gets or sets a delegate that creates an expression. + /// public Func CreateExpression { get; init; } = default!; + + /// + /// Gets or sets a delegate that creates a memory block reference. + /// public Func CreateBlockReference { get; init; } = default!; + + /// + /// Gets or sets a delegate that creates a serializable object. + /// public Func CreateSerializableObject { get; init; } = default!; } +/// +/// Contextual information for creating an expression. +/// +/// The JSON element containing the expression. +/// The JSON serializer options. public record ExpressionConstructorContext(JsonElement Element, JsonSerializerOptions SerializerOptions); +/// +/// Contextual information for creating a memory block reference. +/// +/// The expression. public record BlockReferenceConstructorContext(IExpression Expression) { + /// + /// Gets the expression. + /// + /// The expression type. + /// The expression. public T GetExpression() => (T)Expression; } +/// +/// Contextual information for creating a serializable object. +/// +/// The expression. public record SerializableObjectConstructorContext(IExpression Expression) { + /// + /// Gets the expression. + /// + /// The expression type. + /// The expression. public T GetExpression() => (T)Expression; } \ No newline at end of file diff --git a/src/modules/Elsa.Expressions/Models/Literal.cs b/src/modules/Elsa.Expressions/Models/Literal.cs index ea03620c2..c81a4d3e2 100644 --- a/src/modules/Elsa.Expressions/Models/Literal.cs +++ b/src/modules/Elsa.Expressions/Models/Literal.cs @@ -1,28 +1,50 @@ namespace Elsa.Expressions.Models; +/// +/// A literal expression that represents a constant value. +/// public class Literal : MemoryBlockReference { + /// public Literal() { } + /// public Literal(object? value, string? id = default) : base(id!) { Value = value; } + /// + /// Gets the value of the literal. + /// public object? Value { get; } + + /// public override MemoryBlock Declare() => new(); + /// + /// Creates a literal expression from a value. + /// + /// The value. + /// The value type. + /// A literal expression. public static Literal From(T value) => new Literal(value); } +/// +/// A literal expression that represents a constant value. +/// +/// The value type. public class Literal : Literal { + /// public Literal() { } + /// public Literal(T value, string? id = default) : base(value!, id) { } diff --git a/src/modules/Elsa.Expressions/Services/ExpressionHandlerRegistry.cs b/src/modules/Elsa.Expressions/Services/ExpressionHandlerRegistry.cs index 02a81f2f9..e8f6df89b 100644 --- a/src/modules/Elsa.Expressions/Services/ExpressionHandlerRegistry.cs +++ b/src/modules/Elsa.Expressions/Services/ExpressionHandlerRegistry.cs @@ -17,11 +17,11 @@ public class ExpressionHandlerRegistry : IExpressionHandlerRegistry private IDictionary Dictionary { get; } - public void Register(Type expression, Type handler) => Dictionary.Add(expression, handler); + public void Register(Type expressionType, Type handler) => Dictionary.Add(expressionType, handler); - public IExpressionHandler? GetHandler(IExpression input) + public IExpressionHandler? GetHandler(IExpression expression) { - var expressionType = input.GetType(); + var expressionType = expression.GetType(); if (expressionType.IsConstructedGenericType) expressionType = expressionType.BaseType; diff --git a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs index 0e60411ed..e34307a98 100644 --- a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs +++ b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs @@ -143,7 +143,7 @@ public static class ActivityExecutionContextExtensions /// The name of the variable. /// The type of the variable. /// The variable if found, otherwise null. - public static T? GetVariableByName(this ActivityExecutionContext context, string name) => context.ExpressionExecutionContext.GetVariableByName(name); + public static T? GetVariable(this ActivityExecutionContext context, string name) => context.ExpressionExecutionContext.GetVariable(name); /// /// Returns a dictionary of variable keys and their values across scopes. diff --git a/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs b/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs index 9a94a8714..e3a003fee 100644 --- a/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs +++ b/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs @@ -45,9 +45,9 @@ public static class ExpressionExecutionContextExtensions public static T? Get(this ExpressionExecutionContext context, Input? input) => input != null ? context.GetBlock(input.MemoryBlockReference).Value.ConvertTo() : default; public static T? Get(this ExpressionExecutionContext context, Output output) => context.GetBlock(output.MemoryBlockReference).Value.ConvertTo(); public static object? Get(this ExpressionExecutionContext context, Output output) => context.GetBlock(output.MemoryBlockReference).Value; - public static T? GetVariableByName(this ExpressionExecutionContext context, string name) => (T?)context.GetVariableByName(name)?.Value; + public static T? GetVariable(this ExpressionExecutionContext context, string name) => (T?)context.GetVariable(name)?.Value; - private static Variable? GetVariableByName(this ExpressionExecutionContext context, string name) + private static Variable? GetVariable(this ExpressionExecutionContext context, string name) { foreach (var block in context.Memory.Blocks.Where(b => b.Value.Metadata is VariableBlockMetadata)) { @@ -56,12 +56,12 @@ public static class ExpressionExecutionContextExtensions return metadata.Variable; } - return context.ParentContext?.GetVariableByName(name); + return context.ParentContext?.GetVariable(name); } public static Variable CreateVariable(this ExpressionExecutionContext context, string name, T? value, Type? storageDriverType = null, Action? configure = default) { - var existingVariable = context.GetVariableByName(name); + var existingVariable = context.GetVariable(name); if(existingVariable != null) throw new Exception($"Variable {name} already exists in the context."); @@ -76,7 +76,7 @@ public static class ExpressionExecutionContextExtensions public static Variable SetVariable(this ExpressionExecutionContext context, string name, T? value, Action? configure = default) { - var variable = context.GetVariableByName(name); + var variable = context.GetVariable(name); if(variable is null) throw new Exception($"Variable {name} not found in the context."); diff --git a/test/integration/Elsa.IntegrationTests/Scenarios/SetGetVariables/Workflows.cs b/test/integration/Elsa.IntegrationTests/Scenarios/SetGetVariables/Workflows.cs index ad2fe45dd..2ce0e5aa3 100644 --- a/test/integration/Elsa.IntegrationTests/Scenarios/SetGetVariables/Workflows.cs +++ b/test/integration/Elsa.IntegrationTests/Scenarios/SetGetVariables/Workflows.cs @@ -68,9 +68,9 @@ class SetGetNamedVariableWorkflow : WorkflowBase Activities = { - new WriteLine(context => $"Foo = {context.GetVariableByName("Foo")}"), + new WriteLine(context => $"Foo = {context.GetVariable("Foo")}"), Inline.From(context => context.SetVariable("Foo", "Baz")), - new WriteLine(context => $"Foo = {context.GetVariableByName("Foo")}"), + new WriteLine(context => $"Foo = {context.GetVariable("Foo")}"), } }; } diff --git a/test/unit/Elsa.Workflows.Core.UnitTests/ExpressionExecutionContextExtensionsTests.cs b/test/unit/Elsa.Workflows.Core.UnitTests/ExpressionExecutionContextExtensionsTests.cs index 960389be2..4c7d82450 100644 --- a/test/unit/Elsa.Workflows.Core.UnitTests/ExpressionExecutionContextExtensionsTests.cs +++ b/test/unit/Elsa.Workflows.Core.UnitTests/ExpressionExecutionContextExtensionsTests.cs @@ -7,7 +7,7 @@ namespace Elsa.Workflows.Core.UnitTests; public class ExpressionExecutionContextExtensionsTests { [Fact] - public void GetVariableByName_ReturnsVariable_WhenVariableExists() + public void GetVariable_ReturnsVariable_WhenVariableExists() { // Arrange var variable = new Variable("test", 5); @@ -19,21 +19,21 @@ public class ExpressionExecutionContextExtensionsTests var context = new ExpressionExecutionContext(null!, memoryRegister); // Act - var result = context.GetVariableByName("test"); + var result = context.GetVariable("test"); // Assert Assert.Equal(5, result); } [Fact] - public void GetVariableByName_ReturnsNull_WhenVariableDoesNotExist() + public void GetVariable_ReturnsNull_WhenVariableDoesNotExist() { // Arrange var memoryRegister = new MemoryRegister(new Dictionary()); var context = new ExpressionExecutionContext(null!, memoryRegister); // Act - var result = context.GetVariableByName("nonexistent"); + var result = context.GetVariable("nonexistent"); // Assert Assert.Null(result); @@ -66,7 +66,7 @@ public class ExpressionExecutionContextExtensionsTests context.CreateVariable("newVariable", 10); // Assert - var variable = context.GetVariableByName("newVariable"); + var variable = context.GetVariable("newVariable"); Assert.Equal(10, variable); } @@ -97,7 +97,7 @@ public class ExpressionExecutionContextExtensionsTests context.SetVariable("test", 10); // Assert - var updatedVariable = context.GetVariableByName("test"); + var updatedVariable = context.GetVariable("test"); Assert.Equal(10, updatedVariable); } }