зеркало из https://github.com/microsoft/Forge.git
Addressing feedback.
This commit is contained in:
Родитель
08ced6b6f0
Коммит
74de6e09e3
|
@ -40,6 +40,21 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.CodeAnalysis, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.CSharp.Scripting, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.Scripting.1.3.2\lib\dotnet\Microsoft.CodeAnalysis.CSharp.Scripting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.Scripting, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.CodeAnalysis.Scripting.Common.1.3.2\lib\dotnet\Microsoft.CodeAnalysis.Scripting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Metadata, Version=1.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
|
||||
</Reference>
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
public void TestExecutor_Success_bool()
|
||||
{
|
||||
this.UserContext.Foo = "Bar";
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
string expression = "UserContext.Foo == \"Bar\"";
|
||||
|
||||
Assert.IsTrue(ex.Execute<bool>(expression).GetAwaiter().GetResult(), "Expected ExpressionExecutor to successfully evaluate a true expression.");
|
||||
|
@ -55,7 +55,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
{
|
||||
// Note that long requires casting where int does not.
|
||||
this.UserContext.Foo = (long)1000;
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
string expression = "UserContext.Foo";
|
||||
|
||||
Assert.AreEqual((long)1000, ex.Execute<long>(expression).GetAwaiter().GetResult(), "Expected ExpressionExecutor to successfully evaluate the expression.");
|
||||
|
@ -65,7 +65,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
public void TestExecutor_Success_int()
|
||||
{
|
||||
this.UserContext.Foo = 1000;
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
string expression = "UserContext.Foo";
|
||||
|
||||
Assert.AreEqual(1000, ex.Execute<int>(expression).GetAwaiter().GetResult(), "Expected ExpressionExecutor to successfully evaluate the expression.");
|
||||
|
@ -75,7 +75,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
public void TestExecutor_Success_ExecuteTwice()
|
||||
{
|
||||
this.UserContext.Foo = "Bar";
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
string expression = "UserContext.Foo == \"Bar\" && UserContext.GetTopic(\"TopicName\").ResourceType == \"Node\"";
|
||||
|
||||
// Test - confirm Execute can compile and execute the same code twice without crashing.
|
||||
|
@ -87,7 +87,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
public void TestExecutor_Fail_MissingDefinitions()
|
||||
{
|
||||
this.UserContext.Foo = "Bar";
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
string expression = "UserContext.Bar == \"Bar\"";
|
||||
|
||||
try
|
||||
|
@ -104,7 +104,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
public void TestExecutor_Fail_BadExpression()
|
||||
{
|
||||
this.UserContext.Foo = "Bar";
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
string expression = "UserContext.Foo";
|
||||
|
||||
Assert.ThrowsException<InvalidCastException>(() =>
|
||||
|
@ -119,7 +119,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
this.UserContext.Foo = ExternalTestType.TestEnum;
|
||||
List<Type> dependencies = new List<Type>();
|
||||
dependencies.Add(typeof(ExternalTestType));
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, dependencies, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext, dependencies: dependencies);
|
||||
string expression = "UserContext.Foo.ToString() == ExternalTestType.TestEnum.ToString()";
|
||||
Assert.IsTrue(ex.Execute<bool>(expression).GetAwaiter().GetResult(), "Expected ExpressionExecutor to successfully evaluate a true expression.");
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
public void TestExecutor_Fail_CompileExpressionWithMissingDependencies()
|
||||
{
|
||||
this.UserContext.Foo = ExternalTestType.ExampleEnum;
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
string expression = "UserContext.Foo == ExternalTestType.ExampleEnum";
|
||||
|
||||
try
|
||||
|
@ -149,7 +149,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
List<Type> dependencies = new List<Type>();
|
||||
dependencies.Add(typeof(ExternalTestType));
|
||||
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, dependencies, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext, dependencies: dependencies);
|
||||
string expression = "UserContext.Foo == ExternalTestType.TestEnum && UserContext.Bar == DiffNamespaceType.TestOne";
|
||||
|
||||
try
|
||||
|
@ -170,7 +170,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
List<Type> dependencies = new List<Type>();
|
||||
dependencies.Add(typeof(ExternalTestType));
|
||||
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, dependencies, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext, dependencies: dependencies);
|
||||
string expression = "UserContext.Foo.ToString() == ExternalTestType.TestEnum.ToString() && UserContext.Bar.ToString() == TestType.Test.ToString()";
|
||||
Assert.IsTrue(ex.Execute<bool>(expression).GetAwaiter().GetResult(), "Expected ExpressionExecutor to successfully evaluate a true expression.");
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
dependencies.Add(typeof(Type));
|
||||
|
||||
// Default dependencies are expected to be tossed away internally in ExpressionExecutor.
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
string expression = "UserContext.Foo == \"Foo\"";
|
||||
Assert.IsTrue(ex.Execute<bool>(expression).GetAwaiter().GetResult(), "Expected ExpressionExecutor to successfully evaluate a true expression.");
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
[TestMethod]
|
||||
public void TestExecutor_Success_ChangingFunctionDefinition()
|
||||
{
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
|
||||
// Rewritting GetCount to return 2
|
||||
string expression="UserContext.GetCount = new Func<int>(() => 2)";
|
||||
|
@ -206,7 +206,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
[TestMethod]
|
||||
public void TestExecutor_Fail_ChangingFunctionReturnType()
|
||||
{
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
|
||||
// Changing return type of GetCount
|
||||
string expression = "UserContext.GetCount = new Func<string>(() => \"Test\")";
|
||||
|
@ -220,7 +220,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
[TestMethod]
|
||||
public void TestExecutor_Success_ChangingFunctionReturnType()
|
||||
{
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
|
||||
// Changing return type of GetCount
|
||||
string expression = "UserContext.GetCount = new Func<string>(() => \"Test\")";
|
||||
|
@ -233,7 +233,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
[TestMethod]
|
||||
public void TestExecutor_Fail_ExecutingMultipleStatements()
|
||||
{
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
|
||||
// Changing return type of GetCount
|
||||
string expression = "int x = UserContext.GetCount() + 5; UserContext.GetCount = new Func<int>(() => x); return UserContext.GetCount()";
|
||||
|
@ -255,7 +255,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
string expression = "(Func<bool>)(() => {return UserContext.Foo == \"Bar\";})";
|
||||
|
||||
// Casting the expression to Func<bool> since the executor will return a delegate of type Func<bool>
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
dynamic expressionResult = ex.Execute<Delegate>(expression).GetAwaiter().GetResult();
|
||||
|
||||
if (expressionResult.GetType() == typeof(Func<bool>))
|
||||
|
@ -278,7 +278,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
string expression = "(Func<Task<bool>>)(() => {return Task.FromResult(UserContext.Foo == \"Bar\");})";
|
||||
|
||||
// Casting the expression to Func<bool> since the executor will return a delegate of type Func<bool>
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
dynamic expressionResult = ex.Execute<Delegate>(expression).GetAwaiter().GetResult();
|
||||
|
||||
if (expressionResult.GetType() == typeof(Func<Task<bool>>))
|
||||
|
@ -301,7 +301,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
string expression = "UserContext.Foo == \"Bar\" && UserContext.GetTopic(\"TopicName\").ResourceType == \"Node\"";
|
||||
|
||||
// Test - confirm ExpressionExecutor script cache does not contain script before executing.
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
Assert.IsFalse(ex.ScriptCacheContainsKey(expression));
|
||||
|
||||
// Test - confirm ExpressionExecutor script cache does contain script after executing.
|
||||
|
@ -313,7 +313,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
public void TestExecutor_TreeInput_Success()
|
||||
{
|
||||
object treeInput = "TestValue";
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, treeInput);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext, dependencies: null, scriptCache: null, treeInput: treeInput);
|
||||
string expression = "TreeInput == \"TestValue\"";
|
||||
|
||||
Assert.IsTrue(ex.Execute<bool>(expression).GetAwaiter().GetResult(), "Expected ExpressionExecutor to successfully evaluate a true expression using TreeInput.");
|
||||
|
@ -326,7 +326,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
treeInput["StringProperty"] = "TestValue";
|
||||
treeInput["IntProperty"] = 10;
|
||||
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, treeInput);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext, dependencies: null, scriptCache: null, treeInput: treeInput);
|
||||
string expression = "TreeInput.StringProperty == \"TestValue\" && TreeInput.IntProperty == 10";
|
||||
|
||||
Assert.IsTrue(ex.Execute<bool>(expression).GetAwaiter().GetResult(), "Expected ExpressionExecutor to successfully evaluate a true expression using TreeInput as JObject.");
|
||||
|
@ -335,7 +335,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
[TestMethod]
|
||||
public void TestExecutor_TreeInputNull_Success()
|
||||
{
|
||||
ExpressionExecutor ex = new ExpressionExecutor(null, this.UserContext, null, null);
|
||||
ExpressionExecutor ex = new ExpressionExecutor(session: null, userContext: this.UserContext);
|
||||
string expression = "TreeInput == null";
|
||||
|
||||
Assert.IsTrue(ex.Execute<bool>(expression).GetAwaiter().GetResult(), "Expected ExpressionExecutor to successfully evaluate a true expression using TreeInput as null.");
|
||||
|
|
|
@ -16,8 +16,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Selection"",
|
||||
""ChildSelector"":
|
||||
[
|
||||
""ChildSelector"": [
|
||||
{
|
||||
""Label"": ""Node"",
|
||||
""ShouldSelect"": ""C#|UserContext.ResourceType == \""Node\"""",
|
||||
|
@ -32,8 +31,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
},
|
||||
""Container"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Container_CollectDiagnosticsAction"": {
|
||||
""Action"": ""CollectDiagnosticsAction"",
|
||||
""Input"":
|
||||
|
@ -42,8 +40,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
}
|
||||
}
|
||||
},
|
||||
""ChildSelector"":
|
||||
[
|
||||
""ChildSelector"": [
|
||||
{
|
||||
""Label"": ""Label"",
|
||||
""ShouldSelect"": ""C#|Session.GetLastActionResponse().Status == \""Success\"""",
|
||||
|
@ -53,14 +50,12 @@ namespace Forge.TreeWalker.UnitTests
|
|||
},
|
||||
""Tardigrade"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Tardigrade_TardigradeAction"": {
|
||||
""Action"": ""TardigradeAction""
|
||||
}
|
||||
},
|
||||
""ChildSelector"":
|
||||
[
|
||||
""ChildSelector"": [
|
||||
{
|
||||
""Label"": ""Label"",
|
||||
""ShouldSelect"": ""C#|Session.GetLastActionResponse().Status == \""Success\"""",
|
||||
|
@ -76,16 +71,13 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string ActionException_Fail = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestDelayExceptionAction"": {
|
||||
""Action"": ""TestDelayExceptionAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""ThrowException"": true
|
||||
}
|
||||
}
|
||||
|
@ -96,16 +88,13 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string ActionException_ContinuationOnRetryExhaustion = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestDelayExceptionAction"": {
|
||||
""Action"": ""TestDelayExceptionAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""ThrowException"": true
|
||||
},
|
||||
""ContinuationOnRetryExhaustion"": true
|
||||
|
@ -117,16 +106,13 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string ActionDelay_Fail = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestDelayExceptionAction"": {
|
||||
""Action"": ""TestDelayExceptionAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""DelayMilliseconds"": 50
|
||||
},
|
||||
""Timeout"": 10,
|
||||
|
@ -138,16 +124,13 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string ActionDelay_ContinuationOnTimeout = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestDelayExceptionAction"": {
|
||||
""Action"": ""TestDelayExceptionAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""DelayMilliseconds"": 50
|
||||
},
|
||||
""Timeout"": 10,
|
||||
|
@ -160,22 +143,18 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string ActionDelay_ContinuationOnTimeout_RetryPolicy_TimeoutInAction = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestDelayExceptionAction"": {
|
||||
""Action"": ""TestDelayExceptionAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""DelayMilliseconds"": 50,
|
||||
""ThrowException"": true
|
||||
},
|
||||
""Timeout"": 100,
|
||||
""RetryPolicy"":
|
||||
{
|
||||
""RetryPolicy"": {
|
||||
""Type"": ""FixedInterval"",
|
||||
""MinBackoffMs"": 25
|
||||
},
|
||||
|
@ -188,22 +167,18 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string ActionDelay_ContinuationOnTimeout_RetryPolicy_TimeoutBetweenRetries = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestDelayExceptionAction"": {
|
||||
""Action"": ""TestDelayExceptionAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""DelayMilliseconds"": 25,
|
||||
""ThrowException"": true
|
||||
},
|
||||
""Timeout"": 50,
|
||||
""RetryPolicy"":
|
||||
{
|
||||
""RetryPolicy"": {
|
||||
""Type"": ""FixedInterval"",
|
||||
""MinBackoffMs"": 100
|
||||
},
|
||||
|
@ -216,12 +191,10 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string NoChildMatch = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Selection"",
|
||||
""ChildSelector"":
|
||||
[
|
||||
""ChildSelector"": [
|
||||
{
|
||||
""Label"": ""Label"",
|
||||
""ShouldSelect"": ""C#|false"",
|
||||
|
@ -238,27 +211,22 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string TestEvaluateInputTypeAction = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestEvaluateInputTypeAction"": {
|
||||
""Action"": ""TestEvaluateInputTypeAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""Command"": ""tasklist"",
|
||||
""IntExpression"": ""C#<Int64>|UserContext.GetCount()"",
|
||||
""BoolExpression"": ""C#|true"",
|
||||
""NestedObject"":
|
||||
{
|
||||
""NestedObject"": {
|
||||
""Name"": ""C#|string.Format(\""{0}_{1}\"", \""MyName\"", UserContext.Name)"",
|
||||
""Value"": ""MyValue"",
|
||||
""IntPropertyInObject"": ""C#<Int64>|UserContext.GetCount()""
|
||||
},
|
||||
""ObjectArray"":
|
||||
[
|
||||
""ObjectArray"": [
|
||||
{
|
||||
""Name"": ""C#|UserContext.Name"",
|
||||
""Value"": ""FirstValue""
|
||||
|
@ -268,8 +236,15 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Value"": ""SecondValue""
|
||||
}
|
||||
],
|
||||
""StringArray"": [""C#|UserContext.Name"", ""value2""],
|
||||
""LongArray"": [""C#<Int64>|(long)UserContext.GetCount()"", 3, 2],
|
||||
""StringArray"": [
|
||||
""C#|UserContext.Name"",
|
||||
""value2""
|
||||
],
|
||||
""LongArray"": [
|
||||
""C#<Int64>|(long)UserContext.GetCount()"",
|
||||
3,
|
||||
2
|
||||
],
|
||||
""BoolDelegate"": ""C#|(Func<bool>)(() => {return UserContext.GetCount() == 1;})"",
|
||||
""BoolDelegateAsync"": ""C#|(Func<Task<bool>>)(async() => { return await UserContext.GetCountAsync() == 2; })"",
|
||||
""StringDictionary"": {
|
||||
|
@ -294,16 +269,13 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string TestEvaluateInputType_FailOnField_Action = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestEvaluateInputType_FailOnField_Action"": {
|
||||
""Action"": ""TestEvaluateInputType_FailOnField_Action"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""UnexpectedField"": true
|
||||
},
|
||||
""ContinuationOnRetryExhaustion"": true
|
||||
|
@ -316,16 +288,13 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string TestEvaluateInputTypeAction_UnexpectedPropertyFail = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestEvaluateInputTypeAction"": {
|
||||
""Action"": ""TestEvaluateInputTypeAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""UnexpectedProperty"": true
|
||||
},
|
||||
""ContinuationOnRetryExhaustion"": true
|
||||
|
@ -338,16 +307,13 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string TestEvaluateInputType_FailOnNonEmptyCtor_Action = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_TestEvaluateInputType_FailOnNonEmptyCtor_Action"": {
|
||||
""Action"": ""TestEvaluateInputType_FailOnNonEmptyCtor_Action"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""BoolProperty"": true
|
||||
},
|
||||
""ContinuationOnRetryExhaustion"": true
|
||||
|
@ -360,16 +326,13 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string LeafNodeSummaryAction = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Leaf"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_LeafNodeSummaryAction"": {
|
||||
""Action"": ""LeafNodeSummaryAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""Status"": ""Success"",
|
||||
""StatusCode"": 1,
|
||||
""Output"": ""TheResult""
|
||||
|
@ -383,22 +346,18 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string LeafNodeSummaryAction_InputIsActionResponse = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Action"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_CollectDiagnosticsAction"": {
|
||||
""Action"": ""CollectDiagnosticsAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""Command"": ""TheCommand""
|
||||
}
|
||||
}
|
||||
},
|
||||
""ChildSelector"":
|
||||
[
|
||||
""ChildSelector"": [
|
||||
{
|
||||
""Label"": ""Label"",
|
||||
""Child"": ""LeafNodeSummaryTest""
|
||||
|
@ -407,8 +366,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
},
|
||||
""LeafNodeSummaryTest"": {
|
||||
""Type"": ""Leaf"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""LeafNodeSummaryTest_LeafNodeSummaryAction"": {
|
||||
""Action"": ""LeafNodeSummaryAction"",
|
||||
""Input"": ""C#|Session.GetLastActionResponse()""
|
||||
|
@ -421,16 +379,13 @@ namespace Forge.TreeWalker.UnitTests
|
|||
|
||||
public const string ExternalExecutors = @"
|
||||
{
|
||||
""Tree"":
|
||||
{
|
||||
""Tree"": {
|
||||
""Root"": {
|
||||
""Type"": ""Leaf"",
|
||||
""Actions"":
|
||||
{
|
||||
""Actions"": {
|
||||
""Root_LeafNodeSummaryAction"": {
|
||||
""Action"": ""LeafNodeSummaryAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""Status"": ""External|StatusResult""
|
||||
}
|
||||
}
|
||||
|
@ -449,8 +404,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Actions"": {
|
||||
""Root_Subroutine"": {
|
||||
""Action"": ""SubroutineAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""TreeName"": ""SubroutineTree"",
|
||||
""TreeInput"": {
|
||||
""TestStatusCode"": 10
|
||||
|
@ -469,8 +423,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Actions"": {
|
||||
""Root_LeafNodeSummaryAction"": {
|
||||
""Action"": ""LeafNodeSummaryAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""Status"": ""Success"",
|
||||
""StatusCode"": ""C#|(int)TreeInput.TestStatusCode""
|
||||
}
|
||||
|
@ -491,8 +444,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Actions"": {
|
||||
""Root_Subroutine"": {
|
||||
""Action"": ""SubroutineAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""TreeName"": ""SubroutineTree"",
|
||||
""TreeInput"": ""TestValue""
|
||||
}
|
||||
|
@ -520,24 +472,21 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Actions"": {
|
||||
""Root_Subroutine_One"": {
|
||||
""Action"": ""SubroutineAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""TreeName"": ""SubroutineTree"",
|
||||
""TreeInput"": ""TestValueOne""
|
||||
}
|
||||
},
|
||||
""Root_Subroutine_Two"": {
|
||||
""Action"": ""SubroutineAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""TreeName"": ""SubroutineTree"",
|
||||
""TreeInput"": ""TestValueTwo""
|
||||
}
|
||||
},
|
||||
""Root_CollectDiagnosticsAction"": {
|
||||
""Action"": ""CollectDiagnosticsAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""Command"": ""TheCommand""
|
||||
}
|
||||
}
|
||||
|
@ -552,8 +501,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Actions"": {
|
||||
""Root_LeafNodeSummaryAction"": {
|
||||
""Action"": ""LeafNodeSummaryAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""Status"": ""C#|(string)TreeInput"",
|
||||
}
|
||||
}
|
||||
|
@ -573,8 +521,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Actions"": {
|
||||
""Root_Subroutine"": {
|
||||
""Action"": ""SubroutineAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""TreeName"": ""SubroutineTree"",
|
||||
""TreeInput"": ""TestValue""
|
||||
}
|
||||
|
@ -615,8 +562,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Action"": ""RevisitAction""
|
||||
}
|
||||
},
|
||||
""ChildSelector"":
|
||||
[
|
||||
""ChildSelector"": [
|
||||
{
|
||||
""Label"": ""Label"",
|
||||
""ShouldSelect"": ""C#|(int)Session.GetLastActionResponse().Output < 3"",
|
||||
|
@ -637,8 +583,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Actions"": {
|
||||
""Root_Subroutine"": {
|
||||
""Action"": ""SubroutineAction"",
|
||||
""Input"":
|
||||
{
|
||||
""Input"": {
|
||||
""TreeName"": ""SubroutineTree""
|
||||
}
|
||||
},
|
||||
|
@ -646,8 +591,7 @@ namespace Forge.TreeWalker.UnitTests
|
|||
""Action"": ""RevisitAction""
|
||||
}
|
||||
},
|
||||
""ChildSelector"":
|
||||
[
|
||||
""ChildSelector"": [
|
||||
{
|
||||
""Label"": ""Label"",
|
||||
""ShouldSelect"": ""C#|(int)Session.GetOutput(\""Root_RevisitAction\"").Output < 3"",
|
||||
|
|
|
@ -41,14 +41,14 @@ namespace Forge.TreeWalker.UnitTests
|
|||
this.jsonSchemaFailureBlacklist = new Dictionary<string, List<string>>()
|
||||
{
|
||||
{
|
||||
"SubroutineAction_FailsOnActionTreeNodeType",
|
||||
nameof(ForgeSchemaHelper.SubroutineAction_FailsOnActionTreeNodeType),
|
||||
new List<string>
|
||||
{
|
||||
"RootTree"
|
||||
}
|
||||
},
|
||||
{
|
||||
"SubroutineAction_FailsOnNoSubroutineAction",
|
||||
nameof(ForgeSchemaHelper.SubroutineAction_FailsOnNoSubroutineAction),
|
||||
new List<string>
|
||||
{
|
||||
"RootTree"
|
||||
|
@ -102,7 +102,6 @@ namespace Forge.TreeWalker.UnitTests
|
|||
bool expectedResult = !(this.jsonSchemaFailureBlacklist.TryGetValue(fieldInfo.Name, out List<string> list) && list.Contains(treeName));
|
||||
jsonTrees.Add(new Tuple<string, bool>(jsonSubSchema, expectedResult));
|
||||
}
|
||||
Console.WriteLine("DICTIONARY NO THROW");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
|
|
@ -742,9 +742,9 @@ namespace Forge.TreeWalker.UnitTests
|
|||
string treeNodeKey,
|
||||
dynamic properties,
|
||||
dynamic userContext,
|
||||
CancellationToken token,
|
||||
string treeName,
|
||||
Guid rootSessionId)
|
||||
Guid rootSessionId,
|
||||
CancellationToken token)
|
||||
{
|
||||
string serializeProperties = JsonConvert.SerializeObject(properties);
|
||||
|
||||
|
@ -760,9 +760,9 @@ namespace Forge.TreeWalker.UnitTests
|
|||
string treeNodeKey,
|
||||
dynamic properties,
|
||||
dynamic userContext,
|
||||
CancellationToken token,
|
||||
string treeName,
|
||||
Guid rootSessionId)
|
||||
Guid rootSessionId,
|
||||
CancellationToken token)
|
||||
{
|
||||
Console.WriteLine(string.Format(
|
||||
"OnAfterVisitNode: SessionId: {0}, TreeNodeKey: {1}, Properties: {2}.",
|
||||
|
|
|
@ -69,9 +69,30 @@ namespace Forge.TreeWalker
|
|||
/// <param name="session">The tree session.</param>
|
||||
/// <param name="userContext">The dynamic user context.</param>
|
||||
/// <param name="dependencies">Type dependencies required to compile the schema. Can be null if no external dependencies required.</param>
|
||||
/// <param name="treeInput">The dynamic TreeInput object for this tree walking session.</param>
|
||||
public ExpressionExecutor(ITreeSession session, object userContext, List<Type> dependencies, object treeInput)
|
||||
: this(session, userContext, dependencies, new ConcurrentDictionary<string, Script<object>>(), treeInput)
|
||||
/// <param name="scriptCache">Script cache used to cache and re-use compiled Roslyn scripts.</param>
|
||||
public ExpressionExecutor(ITreeSession session, object userContext, List<Type> dependencies, ConcurrentDictionary<string, Script<object>> scriptCache)
|
||||
: this(session, userContext, dependencies, scriptCache, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates the ExpressionExecutor class with objects that can be referenced in the schema.
|
||||
/// </summary>
|
||||
/// <param name="session">The tree session.</param>
|
||||
/// <param name="userContext">The dynamic user context.</param>
|
||||
/// <param name="dependencies">Type dependencies required to compile the schema. Can be null if no external dependencies required.</param>
|
||||
public ExpressionExecutor(ITreeSession session, object userContext, List<Type> dependencies)
|
||||
: this(session, userContext, dependencies, new ConcurrentDictionary<string, Script<object>>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates the ExpressionExecutor class with objects that can be referenced in the schema.
|
||||
/// </summary>
|
||||
/// <param name="session">The tree session.</param>
|
||||
/// <param name="userContext">The dynamic user context.</param>
|
||||
public ExpressionExecutor(ITreeSession session, object userContext)
|
||||
: this(session, userContext, null)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ namespace Forge.TreeWalker
|
|||
/// <param name="treeNodeKey">The key of the current tree node being visited by Forge.</param>
|
||||
/// <param name="properties">The additional properties for this node.</param>
|
||||
/// <param name="userContext">The dynamic user-defined context object.</param>
|
||||
/// <param name="token">The cancellation token.</param>
|
||||
/// <param name="treeName">The name of the ForgeTree in the JsonSchema.</param>
|
||||
/// <param name="rootSessionId">The unique identifier for the root/parent tree walking session.</param>
|
||||
Task BeforeVisitNode(Guid sessionId, string treeNodeKey, dynamic properties, object userContext, CancellationToken token, string treeName, Guid rootSessionId);
|
||||
/// <param name="token">The cancellation token.</param>
|
||||
Task BeforeVisitNode(Guid sessionId, string treeNodeKey, dynamic properties, object userContext, string treeName, Guid rootSessionId, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// The callback Task that is awaited after visiting each node.
|
||||
|
@ -37,9 +37,9 @@ namespace Forge.TreeWalker
|
|||
/// <param name="treeNodeKey">The key of the current tree node being visited by Forge.</param>
|
||||
/// <param name="properties">The additional properties for this node.</param>
|
||||
/// <param name="userContext">The dynamic user-defined context object.</param>
|
||||
/// <param name="token">The cancellation token.</param>
|
||||
/// <param name="treeName">The name of the ForgeTree in the JsonSchema.</param>
|
||||
/// <param name="rootSessionId">The unique identifier for the root/parent tree walking session.</param>
|
||||
Task AfterVisitNode(Guid sessionId, string treeNodeKey, dynamic properties, object userContext, CancellationToken token, string treeName, Guid rootSessionId);
|
||||
/// <param name="token">The cancellation token.</param>
|
||||
Task AfterVisitNode(Guid sessionId, string treeNodeKey, dynamic properties, object userContext, string treeName, Guid rootSessionId, CancellationToken token);
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ namespace Forge.TreeWalker
|
|||
/// <param name="parameters">The tree walker parameters of the parent tree walker session.</param>
|
||||
public SubroutineAction(TreeWalkerParameters parameters)
|
||||
{
|
||||
this.parameters = parameters;
|
||||
this.parameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -303,9 +303,9 @@ namespace Forge.TreeWalker
|
|||
current,
|
||||
await this.EvaluateDynamicProperty(this.Schema.Tree[current].Properties, null),
|
||||
this.Parameters.UserContext,
|
||||
this.walkTreeCts.Token,
|
||||
this.Parameters.TreeName,
|
||||
this.Parameters.RootSessionId).ConfigureAwait(false);
|
||||
this.Parameters.RootSessionId,
|
||||
this.walkTreeCts.Token).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -320,9 +320,9 @@ namespace Forge.TreeWalker
|
|||
current,
|
||||
await this.EvaluateDynamicProperty(this.Schema.Tree[current].Properties, null),
|
||||
this.Parameters.UserContext,
|
||||
this.walkTreeCts.Token,
|
||||
this.Parameters.TreeName,
|
||||
this.Parameters.RootSessionId).ConfigureAwait(false);
|
||||
this.Parameters.RootSessionId,
|
||||
this.walkTreeCts.Token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
current = next;
|
||||
|
|
Загрузка…
Ссылка в новой задаче