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
@@ -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
@@ -124,13 +127,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);
}
}
17 changes: 17 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;
@@ -25,6 +26,22 @@ 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.AddSingleton<IFunctionDefinition>(new FunctionDefinition{From = fromFunctionName + "()", To = toExpression});
}

private static void AddStringFunctions(IServiceCollection services)
{
services.AddTransient<IFunction, ConcatFunction>();
18 changes: 18 additions & 0 deletions ExpressionEngine/FunctionDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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
{
/// <summary>
/// The from 'function name' which is replaced
/// </summary>
public string From { get; set; }
/// <summary>
/// The replacement
/// </summary>
public string To { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -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)));
}
}
}
18 changes: 18 additions & 0 deletions ExpressionEngine/IFunctionDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace ExpressionEngine
{
/// <summary>
/// Interface to function definitions
/// </summary>
public interface IFunctionDefinition
{
/// <summary>
/// The name of the 'function' which is replaced
/// </summary>
string From { get; set; }

/// <summary>
/// What it is replaced with
/// </summary>
string To { get; set; }
}
}
2 changes: 1 addition & 1 deletion Test/ExpressionGrammarTest.cs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ public void SetUp()

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

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

[Test]
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
@@ -19,7 +19,7 @@ public void Setup()

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

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

[Test]