Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tst/metadata function #75

Merged
merged 10 commits into from
Mar 18, 2022
19 changes: 17 additions & 2 deletions ExpressionEngine/ExpressionGrammar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ namespace ExpressionEngine
{
public class ExpressionGrammar
{
private readonly IList<IFunctionDefinition> _functionDefinitions;
private readonly Parser<IRule> _method;
private readonly Parser<Task<ValueContainer>> _input;

public ExpressionGrammar(IEnumerable<IFunction> functions)
public ExpressionGrammar(IEnumerable<IFunction> functions, IEnumerable<IFunctionDefinition> functionDefinitions)
{
_functionDefinitions = functionDefinitions?.ToList();

var functionCollection = functions ?? throw new ArgumentNullException(nameof(functions));

#region BasicAuxParsers
Expand Down Expand Up @@ -122,13 +125,25 @@ from t in simpleString.Or(allowedCharacters).Many()

public async ValueTask<string> EvaluateToString(string input)
{
var output = await _input.Parse(input);
var output = await PreAnalyzeAndParse(input);

return output.GetValue<string>();
}

public async ValueTask<ValueContainer> EvaluateToValueContainer(string input)
{
return await PreAnalyzeAndParse(input);
}

private async ValueTask<ValueContainer> PreAnalyzeAndParse(string input)
{
if (_functionDefinitions != null)
{
input = _functionDefinitions.Aggregate(input,
(current, functionDefinition) =>
current.Replace(functionDefinition.From(), functionDefinition.To()));
}

return await _input.Parse(input);
}
}
Expand Down
18 changes: 18 additions & 0 deletions ExpressionEngine/FlowRunnerDependencyExtension.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ExpressionEngine.Functions.Base;
using ExpressionEngine.Functions.CustomException;
using ExpressionEngine.Functions.Implementations.CollectionFunctions;
using ExpressionEngine.Functions.Implementations.ConversionFunctions;
using ExpressionEngine.Functions.Implementations.LogicalComparisonFunctions;
Expand All @@ -25,6 +26,23 @@ public static void AddExpressionEngine(this IServiceCollection services)
services.AddTransient<IFunction, GreaterFunction>();
}

/// <summary>
/// Added FunctionDefinition to service collection.
/// </summary>
/// <param name="services"></param>
/// <param name="fromFunctionName">The name of the function, without function parenthesis</param>
/// <param name="toExpression">The full expression which is inserted</param>
public static void AddFunctionDefinition(this IServiceCollection services, string fromFunctionName, string toExpression)
{
if (fromFunctionName.EndsWith("()"))
{
throw new ArgumentError($"{nameof(fromFunctionName)} cannot end in ()");
}

services.AddTransient<IFunctionDefinition, FunctionDefinition>(_ =>
thygesteffensen marked this conversation as resolved.
Show resolved Hide resolved
new FunctionDefinition(fromFunctionName + "()", toExpression));
}

private static void AddStringFunctions(IServiceCollection services)
{
services.AddTransient<IFunction, ConcatFunction>();
Expand Down
41 changes: 41 additions & 0 deletions ExpressionEngine/FunctionDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace ExpressionEngine
{
/// <summary>
/// A Function Definition is a map to a collected set of functions.
/// - currentCellValue() -> formvalue(logicalName())[idx()][attributeLogicalName()]
/// </summary>
public class FunctionDefinition : IFunctionDefinition
{
private readonly string _from;
private readonly string _to;

/// <summary>
/// Construction a Function Definition
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
public FunctionDefinition(string from, string to)
{
_from = @from;
_to = to;
}

/// <summary>
///
/// </summary>
/// <returns></returns>
public string From()
thygesteffensen marked this conversation as resolved.
Show resolved Hide resolved
{
return _from;
}

/// <summary>
///
/// </summary>
/// <returns></returns>
public string To()
{
return _to;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
}

return new ValueTask<ValueContainer>(new ValueContainer(parameters.Aggregate("",
(current, value) => current + AuxiliaryMethods.VcIsString(value))));
(current, value) => current + value)));
thygesteffensen marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
8 changes: 8 additions & 0 deletions ExpressionEngine/IFunctionDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace ExpressionEngine
{
public interface IFunctionDefinition
{
public string From();
public string To();
thygesteffensen marked this conversation as resolved.
Show resolved Hide resolved
}
}
2 changes: 1 addition & 1 deletion Test/ExpressionGrammarTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public void SetUp()

var functions = new List<IFunction> {_dummyFunction};

_expressionGrammar = new ExpressionGrammar(functions);
_expressionGrammar = new ExpressionGrammar(functions, null);
}

[Test]
Expand Down
47 changes: 47 additions & 0 deletions Test/FunctionDefinitionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Threading.Tasks;
using ExpressionEngine;
using ExpressionEngine.Functions.CustomException;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;

namespace Test
{
public class FunctionDefinitionTests
{
private ServiceCollection _serviceCollection;

[SetUp]
public void Setup()
{
_serviceCollection = new ServiceCollection();
_serviceCollection.AddExpressionEngine();
_serviceCollection.AddFunctionDefinition("addAndConcat", "concat('result of 1+1 is: ', add(1,1))");
}

[TestCase]
public async Task TestFunctionDef()
{
var ee = _serviceCollection.BuildServiceProvider().GetRequiredService<IExpressionEngine>();
const string expectedResult = "result of 1+1 is: 2!";

var actualResult = await ee.Parse("@concat(addAndConcat(), '!')");

Assert.AreEqual(expectedResult, actualResult);
}

[TestCase]
public void TestFunctionException()
{
const string expectedMessage = "fromFunctionName cannot end in ()";

var exception = Assert.Throws<ArgumentError>(() =>
{
_serviceCollection.AddFunctionDefinition("addAndConcat()", "concat('result of 1+1 is: ', add(1,1))");
});

Assert.NotNull(exception);
Assert.AreEqual(expectedMessage,exception.Message);
}
}
}
2 changes: 1 addition & 1 deletion Test/NullCoalescingTest2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void Setup()

var functions = new List<IFunction> {_returnData};

_expressionGrammar = new ExpressionGrammar(functions);
_expressionGrammar = new ExpressionGrammar(functions, null);
}

[Test]
Expand Down