Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
// Licensed under the MIT License.

using System.Collections.Generic;
using Microsoft.Bot.Builder.AI.Luis;
using Microsoft.Bot.Builder.AI.Luis.Testing;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing.Actions;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing.HttpRequestMocks;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing.Mocks;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing.TestActions;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Testing.UserTokenMocks;
using Microsoft.Bot.Builder.Dialogs.Debugging;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Testing
/// Delegate for inspecting or modifying dialog state.
/// </summary>
/// <param name="dc">Dialog context.</param>
public delegate void Inspector(DialogContext dc);
public delegate void DialogContextInspector(DialogContext dc);

/// <summary>
/// Class for inspecting current dialog context.
/// </summary>
public class DialogInspector
internal class DialogInspector
{
private string _rootDialogId;
private readonly string _dialogStateProperty;
Expand Down Expand Up @@ -127,7 +127,7 @@ public Dialog RootDialog
/// <param name="inspector">Inspector for analyzing/modifying dialog context.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>result of the running the logic against the activity.</returns>
public async Task InspectAsync(ITurnContext context, Inspector inspector, CancellationToken cancellationToken = default)
public async Task InspectAsync(ITurnContext context, DialogContextInspector inspector, CancellationToken cancellationToken = default)
{
// This class just lets you load & save memory in parallel
var botStateSet = new BotStateSet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
"user.vip == true"
]
}
},
"description": {
"type": "string",
"title": "Description",
"description": "The description of what the assertion is testing"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public virtual void ValidateReply(Activity activity)
}

/// <inheritdoc/>
public override async Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector)
public override async Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null)
{
var timeout = (int)Timeout;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public CustomEvent([CallerFilePath] string path = "", [CallerLineNumber] int lin
public object Value { get; set; }

/// <inheritdoc/>
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector)
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null)
{
if (Name == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ public MemoryAssertions([CallerFilePath] string path = "", [CallerLineNumber] in
RegisterSourcePath(path, line);
}

/// <summary>
/// Gets or sets the description of this assertion.
/// </summary>
/// <value>Description of what this assertion is.</value>
[JsonProperty("description")]
public string Description { get; set; }

/// <summary>
/// Gets the assertions.
/// </summary>
Expand All @@ -44,27 +51,27 @@ public MemoryAssertions([CallerFilePath] string path = "", [CallerLineNumber] in
public List<string> Assertions { get; } = new List<string>();

/// <inheritdoc/>
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector)
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null)
{
var activity = new Activity();
activity.ApplyConversationReference(adapter.Conversation, isIncoming: true);
activity.Type = "event";
activity.Name = "MemoryAssertions";
activity.Value = Assertions;
await adapter.ProcessActivityAsync(
activity,
async (turnContext, cancellationToken) => await inspector.InspectAsync(turnContext, (dc) =>
{
foreach (var assertion in Assertions)
if (inspector != null)
{
await inspector((dc) =>
{
var (val, error) = Expression.Parse(assertion).TryEvaluate<bool>(dc.State);
if (error != null || !val)
foreach (var assertion in Assertions)
{
throw new Exception($"{assertion} failed");
var (val, error) = Expression.Parse(assertion).TryEvaluate<bool>(dc.State);
if (error != null || !val)
{
throw new Exception($"{assertion} failed");
}
}
}
}).ConfigureAwait(false)).ConfigureAwait(false);
Trace.TraceInformation($"[Turn Ended => MemoryAssertions passed]");
}).ConfigureAwait(false);
Trace.TraceInformation($"[Turn Ended => {Description} MemoryAssertions passed]");
}
else
{
Trace.TraceInformation($"[Turn Ended => No inspector for {Description} MemoryAssertions]");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -45,23 +46,23 @@ public SetProperties([CallerFilePath] string path = "", [CallerLineNumber] int l
public List<PropertyAssignment> Assignments { get; } = new List<PropertyAssignment>();

/// <inheritdoc/>
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector)
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null)
{
var activity = new Activity();
activity.ApplyConversationReference(adapter.Conversation, isIncoming: true);
activity.Type = "event";
activity.Name = "SetProperties";
activity.Value = Assignments;
await adapter.ProcessActivityAsync(
activity,
async (turnContext, cancellationToken) => await inspector.InspectAsync(turnContext, (dc) =>
{
foreach (var assignment in Assignments)
{
dc.State.SetValue(assignment.Property.Value, assignment.Value.Value);
}
}).ConfigureAwait(false)).ConfigureAwait(false);
Trace.TraceInformation($"[Turn Ended => SetProperties completed]");
if (inspector != null)
{
await inspector((dc) =>
{
foreach (var assignment in Assignments)
{
dc.State.SetValue(assignment.Property.Value, assignment.Value.Value);
}
}).ConfigureAwait(false);
Trace.TraceInformation($"[Turn Ended => SetProperties completed]");
}
else
{
throw new Exception("No inspector to use for setting properties");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@

namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Testing
{
/// <summary>
/// Allow inspecting/modifying the current dialog context.
/// </summary>
/// <param name="inspector">Inspector for looking at current dialog context.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public delegate Task Inspector(DialogContextInspector inspector);

/// <summary>
/// Abstract base class for scripted actions.
/// </summary>
Expand All @@ -19,7 +26,7 @@ public abstract class TestAction
/// <param name="callback">Logic for the bot to use.</param>
/// <param name="inspector">Inspector for dialog context.</param>
/// <returns>async task.</returns>
public abstract Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector);
public abstract Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null);

/// <summary>
/// Registers the path to file and callers line.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public UserActivity([CallerFilePath] string path = "", [CallerLineNumber] int li
public string User { get; set; }

/// <inheritdoc/>
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector)
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null)
{
if (Activity == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public UserConversationUpdate([CallerFilePath] string path = "", [CallerLineNumb
public List<string> MembersRemoved { get; } = new List<string>();

/// <inheritdoc/>
public override async Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector)
public override async Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null)
{
var activity = adapter.MakeActivity();
activity.Type = ActivityTypes.ConversationUpdate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public UserDelay([CallerFilePath] string path = "", [CallerLineNumber] int line
public uint Timespan { get; set; }

/// <inheritdoc/>
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector)
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null)
{
await Task.Delay((int)Timespan).ConfigureAwait(false);
Trace.TraceInformation($"[Turn Ended => {Timespan} ms processing UserDelay[{Timespan}]");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public UserSays([CallerFilePath] string path = "", [CallerLineNumber] int line =
public string User { get; set; }

/// <inheritdoc/>
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector)
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null)
{
if (Text == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public UserTyping([CallerFilePath] string path = "", [CallerLineNumber] int line
public string User { get; set; }

/// <inheritdoc/>
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, DialogInspector inspector)
public async override Task ExecuteAsync(TestAdapter adapter, BotCallbackHandler callback, Inspector inspector = null)
{
var typing = adapter.MakeActivity();
typing.Type = ActivityTypes.Typing;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,23 @@ public async Task ExecuteAsync(ResourceExplorer resourceExplorer, [CallerMemberN
userToken.Setup(adapter);
}

var inspector = new DialogInspector(Dialog, resourceExplorer);
async Task Inspect(DialogContextInspector inspector)
{
var di = new DialogInspector(Dialog, resourceExplorer);
var activity = new Activity();
activity.ApplyConversationReference(adapter.Conversation, isIncoming: true);
activity.Type = "event";
activity.Name = "inspector";
await adapter.ProcessActivityAsync(
activity,
async (turnContext, cancellationToken) => await di.InspectAsync(turnContext, inspector).ConfigureAwait(false)).ConfigureAwait(false);
}

if (callback != null)
{
foreach (var testAction in Script)
{
await testAction.ExecuteAsync(adapter, callback, inspector).ConfigureAwait(false);
await testAction.ExecuteAsync(adapter, callback, Inspect).ConfigureAwait(false);
}
}
else
Expand All @@ -176,7 +187,7 @@ public async Task ExecuteAsync(ResourceExplorer resourceExplorer, [CallerMemberN

foreach (var testAction in Script)
{
await testAction.ExecuteAsync(adapter, dm.OnTurnAsync, inspector).ConfigureAwait(false);
await testAction.ExecuteAsync(adapter, dm.OnTurnAsync, Inspect).ConfigureAwait(false);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,6 @@ public DeleteProperties([CallerFilePath] string callerPath = "", [CallerLineNumb
{
dc.State.RemoveValue(property.GetValue(dc.State));
}

// Explicit state change resets retries
dc.State.RemoveValue(DialogPath.Retries);
}

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,6 @@ public DeleteProperty(string property, [CallerFilePath] string callerPath = "",

dc.State.RemoveValue(Property.GetValue(dc.State));

// Explicit state change resets retries
dc.State.RemoveValue(DialogPath.Retries);

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,6 @@ public enum ArrayChangeType

dc.State.SetValue(property, array);

// Explicit state change resets retries
dc.State.RemoveValue(DialogPath.Retries);

if (ResultProperty != null)
{
dc.State.SetValue(this.ResultProperty.GetValue(dc.State), result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,9 @@ public SetProperties([CallerFilePath] string callerPath = "", [CallerLineNumber]
}

value = value?.ReplaceJTokenRecursively(dc.State);

dc.State.SetValue(propValue.Property.GetValue(dc.State), value);
}

// Explicit state change resets retries
dc.State.RemoveValue(DialogPath.Retries);

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,8 @@ public SetProperty([CallerFilePath] string callerPath = "", [CallerLineNumber] i
}

value = value?.ReplaceJTokenRecursively(dc.State);

dc.State.SetValue(this.Property.GetValue(dc.State), value);

// Explicit state change resets retries
dc.State.RemoveValue(DialogPath.Retries);

return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
Expand Down Expand Up @@ -904,6 +903,12 @@ private async Task<bool> ProcessQueuesAsync(ActionContext actionContext, Cancell
val = nextAssignment.Alternatives.ToList();
}

if (nextAssignment.RaisedCount++ == 0)
{
// Reset retries when new form event is first issued
actionContext.State.RemoveValue(DialogPath.Retries);
}

evt = new DialogEvent() { Name = nextAssignment.Event, Value = val, Bubble = false };
if (nextAssignment.Event == AdaptiveEvents.AssignEntity)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ public class EntityAssignment
[JsonProperty("isExpected")]
public bool IsExpected { get; set; }

/// <summary>
/// Gets or sets the number of times event has been raised.
/// </summary>
/// <value>
/// The number of times event has been raised.
/// </value>
[JsonProperty("raisedCount")]
public uint RaisedCount { get; set; } = 0;

/// <summary>
/// Gets the alternative entity assignments.
/// </summary>
Expand Down
Loading