Skip to content

Commit

Permalink
Merge pull request #40 from delegateas/thygesteffensen/dot-index-fix
Browse files Browse the repository at this point in the history
Thygesteffensen/dot index fix
  • Loading branch information
thygesteffensen authored Jul 20, 2021
2 parents 148543d + a51a544 commit c7174be
Show file tree
Hide file tree
Showing 28 changed files with 113 additions and 60 deletions.
11 changes: 11 additions & 0 deletions ExpressionEngine/ExpressionEngineException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace ExpressionEngine
{
internal class ExpressionEngineException : Exception
{
public ExpressionEngineException(string message) : base(message)
{
}
}
}
16 changes: 2 additions & 14 deletions ExpressionEngine/ExpressionGrammar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,7 @@ from index in _method.Or(stringLiteral).Or(integer).Contained(lBracket, rBracket
from nll in nullConditional
from dot in Parse.Char('.')
from index in Parse.AnyChar.Except(
lBracket
.Or(rBracket)
.Or(lParenthesis)
.Or(rParenthesis)
.Or(Parse.Char('@'))
.Or(Parse.Char(','))
.Or(Parse.Char('.'))
.Or(Parse.Char('?'))
Parse.Chars('[', ']', '{', '}', '[', ']', '@', ',', '.', '?')
).Many().Text()
select new IndexRule(new StringLiteralRule(new ValueContainer(index)), nll);

Expand Down Expand Up @@ -123,12 +116,7 @@ from exp in enclosedExpression.Optional()
.Many()
select new ValueTask<ValueContainer>(new ValueContainer(string.Concat(e)));

Parser<ValueTask<ValueContainer>> charPrefixedString =
from at in Parse.Char('@')
from str in Parse.LetterOrDigit.Many().Text().Except(Parse.Chars('{', '@'))
select new ValueTask<ValueContainer>(new ValueContainer(str));

_input = expression.Or(charPrefixedString).Or(joinedString);
_input = expression.Or(joinedString);
}

public async ValueTask<string> EvaluateToString(string input)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
var substring = value.GetValue<string>();
return new ValueTask<ValueContainer>(new ValueContainer(text.Contains(substring)));
default:
throw new PowerAutomateMockUpException($"Cannot perform contains on {collection.Type()}.");
throw new ExpressionEngineException($"Cannot perform contains on {collection.Type()}.");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
ValueContainer.ValueType.Object => new ValueTask<ValueContainer>(new ValueContainer(
value.GetValue<Dictionary<string, ValueContainer>>().Count == 0)),
ValueContainer.ValueType.Null => new ValueTask<ValueContainer>(new ValueContainer(true)),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Empty expression can only operate on String, Array or Object types, not {value.Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
value.GetValue<string>().Substring(0, 1))),
ValueContainer.ValueType.Array => new ValueTask<ValueContainer>(new ValueContainer(
value.GetValue<IEnumerable<ValueContainer>>().First())),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Empty expression can only operate on String or Array types, not {value.Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
{
ValueContainer.ValueType.Array => IntersectList(parameters),
ValueContainer.ValueType.Object => IntersectDict(parameters),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Can only intersect Array and Object, not {parameters[0].Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
value.GetValue<string>().ToCharArray().Last().ToString())),
ValueContainer.ValueType.Array => new ValueTask<ValueContainer>(new ValueContainer(
value.GetValue<IEnumerable<ValueContainer>>().Last())),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Empty expression can only operate on String or Array types, not {value.Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
{
ValueContainer.ValueType.Array => new ValueTask<ValueContainer>(new ValueContainer(
value.GetValue<IEnumerable<ValueContainer>>().Skip(count))),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Empty expression can only operate on String or Array types, not {value.Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
{
ValueContainer.ValueType.Array => new ValueTask<ValueContainer>(new ValueContainer(
value.GetValue<IEnumerable<ValueContainer>>().Take(count))),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Empty expression can only operate on String or Array types, not {value.Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override async ValueTask<ValueContainer> ExecuteFunction(params ValueCont
{
ValueContainer.ValueType.Array => UnionList(parameters),
ValueContainer.ValueType.Object => UnionDict(parameters),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Can only union Array and Object, not {parameters[0].Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
{
ValueContainer.ValueType.String => new ValueTask<ValueContainer>(
new ValueContainer(new[] {parameters[0]})),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Array function can only operate on strings, not {parameters[0].Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
new ValueTask<ValueContainer>(new ValueContainer(
System.Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes(parameters[0].GetValue<string>())))),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Array function can only operate on strings, not {parameters[0].Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
ValueContainer.ValueType.String =>
new ValueTask<ValueContainer>(new ValueContainer(Convert.FromBase64String(parameters[0].GetValue<string>())
.Aggregate("", (s, b) => s + Convert.ToString(b, 2).PadLeft(8, '0')))),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Array function can only operate on strings, not {parameters[0].Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
{
ValueContainer.ValueType.String =>
new ValueTask<ValueContainer>(new ValueContainer(Encoding.UTF8.GetString(Convert.FromBase64String(parameters[0].GetValue<string>())))),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Array function can only operate on strings, not {parameters[0].Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
new ValueTask<ValueContainer>(new ValueContainer(Encoding.UTF8
.GetBytes(parameters[0].GetValue<string>())
.Aggregate("", (s, b) => s + Convert.ToString(b, 2).PadLeft(8, '0')))),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Array function can only operate on strings, not {parameters[0].Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
case "false":
return new ValueTask<ValueContainer>(new ValueContainer(false));
default:
throw new PowerAutomateMockUpException(
throw new ExpressionEngineException(
$"Can only convert 'true' or 'false' to bool, not {parameters[0].GetValue<string>()}.");
}
case ValueContainer.ValueType.Integer:
Expand All @@ -33,7 +33,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
case ValueContainer.ValueType.Boolean:
return new ValueTask<ValueContainer>(parameters[0]);
default:
throw new PowerAutomateMockUpException(
throw new ExpressionEngineException(
$"Array function can only operate on strings, not {parameters[0].Type()}.");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
ValueContainer.ValueType.String =>
new ValueTask<ValueContainer>(new ValueContainer(
$"data:text/plain;charset=utf-8;base64,{System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(parameters[0].GetValue<string>()))}")),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Array function can only operate on strings, not {parameters[0].Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
ValueContainer.ValueType.String =>
new ValueTask<ValueContainer>(new ValueContainer(Encoding.UTF8.GetBytes(parameters[0].GetValue<string>())
.Aggregate("", (s, b) => s + Convert.ToString(b, 2).PadLeft(8, '0')))),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"Array function can only operate on strings, not {parameters[0].Type()}.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public static string VcIsString(ValueContainer vc)
{
return vc.Type() == ValueContainer.ValueType.String
? vc.GetValue<string>()
: throw new PowerAutomateMockUpException("ValueContainer must be of type string.");
: throw new ExpressionEngineException("ValueContainer must be of type string.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
return new ValueTask<ValueContainer>(new ValueContainer(floatValue.ToString(format, CultureInfo.CreateSpecificCulture(locale))));
}

throw new PowerAutomateMockUpException("Expected an numeric value when formatting numbers.");
throw new ExpressionEngineException("Expected an numeric value when formatting numbers.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[
var format = AuxiliaryMethods.VcIsString(parameters[0]);
if (!new[] {"n", "d", "b", "p", "x"}.Contains(format.ToLower()))
{
throw new PowerAutomateMockUpException($"The given format, {format}, is not recognized.");
throw new ExpressionEngineException($"The given format, {format}, is not recognized.");
}

return new ValueTask<ValueContainer>(new ValueContainer(Guid.NewGuid().ToString(format.ToUpper())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[

if (startIndex + length > str.Length)
{
throw new PowerAutomateMockUpException(
throw new ExpressionEngineException(
"The template language function 'substring' parameters are out of range: 'start index' " +
"and 'length' must be non-negative integers and their sum must be no larger than the length of " +
"the string.");
Expand Down
12 changes: 0 additions & 12 deletions ExpressionEngine/PowerAutomateMockUpException.cs

This file was deleted.

6 changes: 5 additions & 1 deletion ExpressionEngine/Rules/AccessValueRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ public async ValueTask<ValueContainer> Evaluate()
}
}

return currentValue;
throw new InvalidTemplateException(
"Unable to process template language expressions in action 'Compose' inputs " +
$"at line 'x' and column 'y': 'The template language expression '{_func.PrettyPrint()}{(nullConditional ? "?" : "")}.{index}' cannot be " +
$"evaluated because property '{index}' cannot be selected. Property selection is not supported on values " +
$"of type '{currentValue.Type()}'.");
}

public string PrettyPrint()
Expand Down
12 changes: 6 additions & 6 deletions ExpressionEngine/ValueContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ public Dictionary<string, ValueContainer> AsDict()
return GetValue<Dictionary<string, ValueContainer>>();
}

throw new PowerAutomateMockUpException("Can't get none object value container as dict.");
throw new ExpressionEngineException("Can't get none object value container as dict.");
}

public override string ToString()
Expand Down Expand Up @@ -412,7 +412,7 @@ private static async ValueTask<ValueContainer> JsonToValueContainer(JToken json,
case JValue jValue:
if (jValue.HasValues)
{
throw new PowerAutomateMockUpException(
throw new ExpressionEngineException(
"When parsing JToken to ValueContainer, the JToken as JValue can only contain one value.");
}

Expand All @@ -427,11 +427,11 @@ private static async ValueTask<ValueContainer> JsonToValueContainer(JToken json,
JTokenType.String => new ValueContainer(jValue.Value<string>()),
JTokenType.None => new ValueContainer(),
JTokenType.Guid => new ValueContainer(jValue.Value<Guid>().ToString()),
_ => throw new PowerAutomateMockUpException(
_ => throw new ExpressionEngineException(
$"{jValue.Type} is not yet supported in ValueContainer conversion")
};
default:
throw new PowerAutomateMockUpException("Could not parse JToken to ValueContainer.");
throw new ExpressionEngineException("Could not parse JToken to ValueContainer.");
}
}

Expand All @@ -443,7 +443,7 @@ private static ValueContainer JArrayToValueContainer(JArray json)
{
if (jToken.GetType() != typeof(JValue))
{
throw new PowerAutomateMockUpException("Json can only contain arrays of primitive types.");
throw new ExpressionEngineException("Json can only contain arrays of primitive types.");
}

var t = (JValue) jToken;
Expand All @@ -462,7 +462,7 @@ private static ValueContainer JArrayToValueContainer(JArray json)
list.Add(new ValueContainer(d));
break;
default:
throw new PowerAutomateMockUpException(
throw new ExpressionEngineException(
$"Type {t.Value.GetType()} is not recognized when converting Json to ValueContainer.");
}
}
Expand Down
18 changes: 17 additions & 1 deletion Test/ExpressionGrammarTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Threading.Tasks;
using ExpressionEngine;
using ExpressionEngine.Functions.Base;
using ExpressionEngine.Functions.CustomException;
using NUnit.Framework;

namespace Test
Expand Down Expand Up @@ -68,7 +69,7 @@ public async Task BooleanTest()
[Test]
public async Task NullConditional()
{
_dummyFunction.ValueContainer = new ValueContainer();
_dummyFunction.ValueContainer = new ValueContainer(new Dictionary<string, ValueContainer>());

const string expressionString = "@dummyFunction()?.name1";

Expand All @@ -77,6 +78,21 @@ public async Task NullConditional()
Assert.NotNull(result);
Assert.AreEqual(ValueContainer.ValueType.Null, result.Type());
}

[Test]
public async Task IndexOnNonObject()
{
_dummyFunction.ValueContainer = new ValueContainer("");

const string expressionString = "@dummyFunction()?.name1";

var exception = Assert.ThrowsAsync<InvalidTemplateException>(async () => await _expressionGrammar.EvaluateToValueContainer(expressionString));

Assert.AreEqual("Unable to process template language expressions in action 'Compose' inputs " +
"at line 'x' and column 'y': 'The template language expression 'dummyFunction()?.name1' cannot be " +
"evaluated because property 'name1' cannot be selected. Property selection is not supported on values " +
"of type 'String'.", exception.Message);
}
}

public class DummyFunction : Function
Expand Down
Loading

0 comments on commit c7174be

Please sign in to comment.