This commit is contained in:
Travis Jensen 2019-12-09 17:10:06 -08:00
Родитель 08ced6b6f0
Коммит 74de6e09e3
9 изменённых файлов: 147 добавлений и 168 удалений

Просмотреть файл

@ -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;