Skip to content

Commit

Permalink
Merge pull request #75 from delegateas/tst/metadata-function
Browse files Browse the repository at this point in the history
Tst/metadata function
  • Loading branch information
thygesteffensen authored Mar 18, 2022
2 parents 1ce30ca + e17932d commit 55c27a2
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 5 deletions.
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 @@ -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);
}
}
Expand Down
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;
Expand All @@ -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>();
Expand Down
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
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)));
}
}
}
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
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

0 comments on commit 55c27a2

Please sign in to comment.