fix: [#4204] Fix remaining eslint warnings - botbuilder-dialogs (2/2) (#4232)

* Fix eslint issues in botbuilder-dialogs (2/2)

* Update botbuilder-dialogs.api doc
This commit is contained in:
Cecilia Avila 2022-07-13 15:20:05 -03:00 коммит произвёл GitHub
Родитель 68f49bac42
Коммит 134d3673ab
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
36 изменённых файлов: 687 добавлений и 551 удалений

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

@ -397,7 +397,7 @@ export enum DialogReason {
replaceCalled = "replaceCalled"
}
// @public (undocumented)
// @public
export class DialogsBotComponent extends BotComponent {
// (undocumented)
configureServices(services: ServiceCollection, configuration: Configuration): void;

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

@ -89,6 +89,7 @@ export class ChoiceFactory {
* @param text (Optional) text of the message.
* @param speak (Optional) SSML to speak for the message.
* @param options (Optional) formatting options to use when rendering as a list.
* @returns The created message activity.
*/
static forChannel(
channelOrContext: string | TurnContext,
@ -134,7 +135,6 @@ export class ChoiceFactory {
}
}
/**
* Creates a message [Activity](xref:botframework-schema.Activity) that includes a [Choice](xref:botbuilder-dialogs.Choice) list that have been added as `HeroCard`'s.
*
@ -172,6 +172,7 @@ export class ChoiceFactory {
* @param text (Optional) text of the message.
* @param speak (Optional) SSML to speak for the message.
* @param options (Optional) formatting options to tweak rendering of list.
* @returns The created message activity.
*/
static inline(
choices: (string | Choice)[],
@ -222,6 +223,7 @@ export class ChoiceFactory {
* @param text (Optional) text of the message.
* @param speak (Optional) SSML to speak for the message.
* @param options (Optional) formatting options to tweak rendering of list.
* @returns The created message activity.
*/
static list(
choices: (string | Choice)[],
@ -263,6 +265,7 @@ export class ChoiceFactory {
* @param choices List of choices to add.
* @param text (Optional) text of the message.
* @param speak (Optional) SSML to speak for the message.
* @returns An activity with choices as suggested actions.
*/
static suggestedAction(choices: (string | Choice)[], text?: string, speak?: string): Partial<Activity> {
// Map choices to actions
@ -291,6 +294,7 @@ export class ChoiceFactory {
* const choices = ChoiceFactory.toChoices(['red', 'green', 'blue']);
* ```
* @param choices List of choices to add.
* @returns A list of choices.
*/
static toChoices(choices: (string | Choice)[] | undefined): Choice[] {
return (choices || [])

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

@ -130,6 +130,7 @@ export interface FoundChoice {
* @param utterance The text or user utterance to search over. For an incoming 'message' activity you can simply use `context.activity.text`.
* @param choices List of choices to search over.
* @param options (Optional) options used to tweak the search that's performed.
* @returns A list of found choices, sorted by most relevant first.
*/
export function findChoices(
utterance: string,

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

@ -78,9 +78,11 @@ export interface SortedValue {
* functions like `findChoices()` and `recognizeChoices()` are layered above this function. In most
* cases its easier to just call one of the higher level functions instead but this function contains
* the fuzzy search algorithm that drives choice recognition.
*
* @param utterance The text or user utterance to search over.
* @param values List of values to search over.
* @param options (Optional) options used to tweak the search that's performed.
* @returns A list of found values.
*/
// tslint:disable-next-line:max-func-body-length
export function findValues(
@ -233,7 +235,7 @@ export function findValues(
const usedTokens: { [index: number]: boolean } = {};
matches.forEach((match: ModelResult<FoundValue>) => {
// Apply filters
let add = !foundIndexes.hasOwnProperty(match.resolution.index);
let add = !Object.prototype.hasOwnProperty.call(foundIndexes, match.resolution.index);
for (let i: number = match.start; i <= match.end; i++) {
if (usedTokens[i]) {
add = false;

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

@ -40,6 +40,7 @@ import { ModelResult } from './modelResult';
* @param utterance The text or user utterance to search over. For an incoming 'message' activity you can simply use `context.activity.text`.
* @param choices List of choices to search over.
* @param options (Optional) options used to tweak the search that's performed.
* @returns A list of found choices, sorted by most relevant first.
*/
export function recognizeChoices(
utterance: string,
@ -63,7 +64,7 @@ export function recognizeChoices(
},
});
}
} catch (e) {
} catch {
// noop
// TODO: Should this log an error or do something?
}

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

@ -14,7 +14,9 @@ import { Converter, ConverterFactory } from './converter';
export abstract class Configurable {
/**
* Fluent method for configuring the object.
*
* @param config Configuration settings to apply.
* @returns The [Configurable](xref:botbuilder-dialogs.Configurable) after the operation is complete.
*/
configure(config: Record<string, unknown>): this {
for (const key in config) {
@ -46,6 +48,10 @@ export abstract class Configurable {
return this;
}
/**
* @param _property The key of the conditional selector configuration.
* @returns The converter for the selector configuration.
*/
getConverter(_property: string): Converter | ConverterFactory {
return undefined;
}

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

@ -22,6 +22,7 @@ export abstract class DialogContainer<O extends object = {}> extends Dialog<O> {
/**
* Creates an inner dialog context for the containers active child.
*
* @param dc Parents dialog context.
* @returns A new dialog context for the active child or `undefined` if there is no active child.
*/
@ -29,7 +30,9 @@ export abstract class DialogContainer<O extends object = {}> extends Dialog<O> {
/**
* Finds a child dialog that was previously added to the container.
*
* @param dialogId ID of the dialog to lookup.
* @returns The Dialog if found; otherwise null.
*/
findDialog(dialogId: string): Dialog | undefined {
return this.dialogs.find(dialogId);
@ -41,6 +44,7 @@ export abstract class DialogContainer<O extends object = {}> extends Dialog<O> {
*
* @param dc The dialog context for the current turn of conversation.
* @param e The event being raised.
* @returns True if the event is handled by the current dialog and bubbling should stop.
*/
async onDialogEvent(dc: DialogContext, e: DialogEvent): Promise<boolean> {
const handled = await super.onDialogEvent(dc, e);
@ -104,6 +108,8 @@ export abstract class DialogContainer<O extends object = {}> extends Dialog<O> {
/**
* Get the current telemetry client.
*
* @returns The [BotTelemetryClient](xref:botbuilder.BotTelemetryClient) to use for logging.
*/
get telemetryClient(): BotTelemetryClient {
return this._telemetryClient;

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

@ -55,7 +55,8 @@ export async function runDialog(
}
const dialogSet = new DialogSet(accessor);
dialogSet.telemetryClient = context.turnState.get<BotTelemetryClient>(BotTelemetryClientKey) ?? dialog.telemetryClient;
dialogSet.telemetryClient =
context.turnState.get<BotTelemetryClient>(BotTelemetryClientKey) ?? dialog.telemetryClient;
dialogSet.add(dialog);
@ -64,6 +65,13 @@ export async function runDialog(
await internalRun(context, dialog.id, dialogContext);
}
/**
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn.
* @param dialogId The dialog ID.
* @param dialogContext The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
* @param dialogStateManagerConfiguration Configuration for the dialog state manager.
* @returns {Promise<DialogTurnResult>} a promise resolving to the dialog turn result.
*/
export async function internalRun(
context: TurnContext,
dialogId: string,
@ -174,8 +182,9 @@ async function innerRun(
/**
* Helper to determine if we should send an EoC to the parent or not.
*
* @param context
* @param turnResult
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn.
* @param turnResult The dialog turn result.
* @returns True if should send EoC, otherwise false.
*/
export function shouldSendEndOfConversationToParent(context: TurnContext, turnResult: DialogTurnResult): boolean {
if (!(turnResult.status == DialogTurnStatus.complete || turnResult.status == DialogTurnStatus.cancelled)) {
@ -241,7 +250,8 @@ export function isFromParentToSkill(context: TurnContext): boolean {
const sendStateSnapshotTrace = async (dialogContext: DialogContext): Promise<void> => {
const adapter = dialogContext.context.adapter;
const claimIdentity = dialogContext.context.turnState.get<ClaimsIdentity>(adapter.BotIdentityKey);
const traceLabel = claimIdentity && SkillValidation.isSkillClaim(claimIdentity.claims) ? 'Skill State' : 'Bot State';
const traceLabel =
claimIdentity && SkillValidation.isSkillClaim(claimIdentity.claims) ? 'Skill State' : 'Bot State';
// Send trace of memory
const snapshot = getActiveDialogContext(dialogContext).state.getMemorySnapshot();

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

@ -95,6 +95,7 @@ export class DialogSet {
/**
* Returns a 32-bit hash of the all the `Dialog.version` values in the set.
*
* @returns A version that will change when any of the child dialogs version changes.
* @remarks
* This hash is persisted to state storage and used to detect changes to a dialog set.
*/
@ -123,17 +124,18 @@ export class DialogSet {
* of "duplicate2".
* @param dialog The dialog or prompt to add.
* If a telemetryClient is present on the dialog set, it will be added to each dialog.
* @returns The dialog set after the operation is complete.
*/
add<T extends Dialog>(dialog: T): this {
if (!(dialog instanceof Dialog)) {
throw new Error(`DialogSet.add(): Invalid dialog being added.`);
throw new Error('DialogSet.add(): Invalid dialog being added.');
}
// Ensure new version hash is computed
this._version = undefined;
// Ensure dialogs ID is unique.
if (this.dialogs.hasOwnProperty(dialog.id)) {
if (Object.prototype.hasOwnProperty.call(this.dialogs, dialog.id)) {
// If we are trying to add the same exact instance, it's not a name collision.
// No operation required since the instance is already in the dialog set.
if (this.dialogs[dialog.id] === dialog) {
@ -143,9 +145,10 @@ export class DialogSet {
// If we are adding a new dialog with a conflicting name, add a suffix to avoid
// dialog name collisions.
let nextSuffix = 2;
// eslint-disable-next-line no-constant-condition
while (true) {
const suffixId = dialog.id + nextSuffix.toString();
if (!this.dialogs.hasOwnProperty(suffixId)) {
if (!Object.prototype.hasOwnProperty.call(this.dialogs, suffixId)) {
dialog.id = suffixId;
break;
} else {
@ -174,12 +177,14 @@ export class DialogSet {
/**
* Creates a dialog context which can be used to work with the dialogs in the set.
*
* @param context Context for the current turn of conversation with the user.
* @returns A promise representing the asynchronous operation.
*/
async createContext(context: TurnContext): Promise<DialogContext> {
if (!this.dialogState) {
throw new Error(
`DialogSet.createContext(): the dialog set was not bound to a stateProperty when constructed.`
'DialogSet.createContext(): the dialog set was not bound to a stateProperty when constructed.'
);
}
const state: DialogState = await this.dialogState.get(context, { dialogStack: [] } as DialogState);
@ -197,13 +202,16 @@ export class DialogSet {
* const dialog = dialogs.find('greeting');
* ```
* @param dialogId ID of the dialog or prompt to lookup.
* @returns The dialog if found; otherwise undefined.
*/
find(dialogId: string): Dialog | undefined {
return this.dialogs.hasOwnProperty(dialogId) ? this.dialogs[dialogId] : undefined;
return Object.prototype.hasOwnProperty.call(this.dialogs, dialogId) ? this.dialogs[dialogId] : undefined;
}
/**
* Set the telemetry client for this dialog set and apply it to all current dialogs.
*
* @returns The [BotTelemetryClient](xref:botbuilder.BotTelemetryClient) to use for logging.
*/
get telemetryClient(): BotTelemetryClient {
return this._telemetryClient;

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

@ -28,7 +28,14 @@ import {
const InitialSettings = z.record(z.unknown());
/**
* Bot component for bot Dialogs.
*/
export class DialogsBotComponent extends BotComponent {
/**
* @param services Services Collection to register.
* @param configuration Configuration for the bot component.
*/
configureServices(services: ServiceCollection, configuration: Configuration): void {
services.composeFactory<MemoryScope[]>('memoryScopes', (memoryScopes) => {
const rootConfiguration = configuration.get();

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

@ -22,6 +22,9 @@ export class DialogsComponentRegistration
pathResolvers: [],
});
/**
* Creates an instance of the [DialogsComponentRegistration](xref:botbuilder-dialogs.DialogsComponentRegistration) class.
*/
constructor() {
super();

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

@ -14,6 +14,7 @@ import { DialogContext } from './dialogContext';
export interface TemplateInterface<T, D = Record<string, unknown>> {
/**
* Given the turn context bind to the data to create the object
*
* @param dialogContext DialogContext.
* @param data Data to bind to.
* @returns Instance of T.

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

@ -19,6 +19,7 @@ import { WaterfallStepContext } from './waterfallStepContext';
* ```TypeScript
* type WaterfallStep<O extends object = {}> = (step: WaterfallStepContext<O>) => Promise<DialogTurnResult>;
* ```
*
* @param O (Optional) type of dialog options passed into the step.
* @param WaterfallStep.step Contextual information for the current step being executed.
*/
@ -91,12 +92,13 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
/**
* Gets the dialog version, composed of the ID and number of steps.
*
* @returns Dialog version, composed of the ID and number of steps.
*/
getVersion(): string {
// Simply return the id + number of steps to help detect when new steps have
// been added to a given waterfall.
return `${ this.id }:${ this.steps.length }`;
return `${this.id}:${this.steps.length}`;
}
/**
@ -136,6 +138,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
* helloDialog.addStep(this.helloWorldStep.bind(this));
* ```
* @param step Asynchronous step function to call.
* @returns Waterfall dialog for fluent calls to `addStep()`.
*/
addStep(step: WaterfallStep<O>): this {
this.steps.push(step);
@ -145,6 +148,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
/**
* Called when the [WaterfallDialog](xref:botbuilder-dialogs.WaterfallDialog) is started and pushed onto the dialog stack.
*
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
* @param options Optional, initial information to pass to the [Dialog](xref:botbuilder-dialogs.Dialog).
* @returns A Promise representing the asynchronous operation.
@ -177,6 +181,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
/**
* Called when the [WaterfallDialog](xref:botbuilder-dialogs.WaterfallDialog) is _continued_, where it is the active dialog and the
* user replies with a new [Activity](xref:botframework-schema.Activity).
*
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
* @returns A Promise representing the asynchronous operation.
* @remarks
@ -196,6 +201,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
/**
* Called when a child [WaterfallDialog](xref:botbuilder-dialogs.WaterfallDialog) completed its turn, returning control to this dialog.
*
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of the conversation.
* @param reason [Reason](xref:botbuilder-dialogs.DialogReason) why the dialog resumed.
* @param result Optional, value returned from the dialog that was called. The type
@ -224,6 +230,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
* }
* ```
* @param step Context object for the waterfall step to execute.
* @returns A promise with the DialogTurnResult.
*/
protected async onStep(step: WaterfallStepContext<O>): Promise<DialogTurnResult> {
// Log Waterfall Step event.
@ -242,6 +249,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
/**
* Executes a step of the [WaterfallDialog](xref:botbuilder-dialogs.WaterfallDialog).
*
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
* @param index The index of the current waterfall step to execute.
* @param reason The [Reason](xref:botbuilder-dialogs.DialogReason) the waterfall step is being executed.
@ -320,6 +328,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
/**
* Identifies the step name by its position index.
*
* @param index Step position
* @returns A string that identifies the step name.
*/

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

@ -40,6 +40,7 @@ export interface WaterfallStepInfo<O extends object> {
/**
* Called to skip to the next waterfall step.
*
* @param result (Optional) result to pass to the next step.
*/
onNext(result?: any): Promise<DialogTurnResult>;
@ -47,6 +48,7 @@ export interface WaterfallStepInfo<O extends object> {
/**
* Context object passed in to a `WaterfallStep`.
*
* @param O (Optional) type of options passed to the steps waterfall dialog in the call to `DialogContext.beginDialog()`.
*/
export class WaterfallStepContext<O extends object = {}> extends DialogContext {
@ -54,6 +56,7 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
/**
* Creates a new WaterfallStepContext instance.
*
* @param dc The dialog context for the current turn of conversation.
* @param info Values to initialize the step context with.
*/
@ -65,6 +68,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
/**
* The index of the current waterfall step being executed.
*
* @returns The index of the current waterfall step being executed.
*/
get index(): number {
return this._info.index;
@ -73,6 +78,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
/**
* Any options passed to the steps waterfall dialog when it was started with
* `DialogContext.beginDialog()`.
*
* @returns Any options the waterfall dialog was called with.
*/
get options(): O {
return this._info.options;
@ -80,6 +87,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
/**
* The reason the waterfall step is being executed.
*
* @returns The reason the waterfall step is being executed.
*/
get reason(): DialogReason {
return this._info.reason;
@ -87,6 +96,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
/**
* Results returned by a dialog or prompt that was called in the previous waterfall step.
*
* @returns The result from the previous waterfall step.
*/
get result(): any {
return this._info.result;
@ -94,6 +105,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
/**
* A dictionary of values which will be persisted across all waterfall steps.
*
* @returns A dictionary of values which will be persisted across all waterfall steps.
*/
get values(): object {
return this._info.values;
@ -108,6 +121,7 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
* return await step.skip();
* ```
* @param result (Optional) result to pass to the next step.
* @returns A promise with the DialogTurnResult.
*/
async next(result?: any): Promise<DialogTurnResult> {
return await this._info.onNext(result);

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

@ -1,5 +1,5 @@
const { ActivityTypes, ConversationState, MemoryStorage, TestAdapter } = require('botbuilder-core');
const { ActivityPrompt, DialogReason, DialogSet, DialogTurnStatus } = require('../');
const { ActivityPrompt, DialogReason, DialogSet, DialogTurnStatus } = require('../');
const assert = require('assert');
class SimpleActivityPrompt extends ActivityPrompt {
@ -17,7 +17,7 @@ describe('ActivityPrompt', function () {
it('should call ActivityPrompt using dc.prompt().', async function () {
// Initialize TestAdapter.
const adapter = new TestAdapter(async turnContext => {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.continueDialog();
@ -35,13 +35,16 @@ describe('ActivityPrompt', function () {
// Create a DialogState property, DialogSet and TextPrompt.
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new SimpleActivityPrompt('prompt', async prompt => {
assert(prompt, `validator missing PromptValidatorContext.`);
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
return true;
}));
dialogs.add(
new SimpleActivityPrompt('prompt', async (prompt) => {
assert(prompt, 'validator missing PromptValidatorContext.');
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
return true;
})
);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please send an activity.')
.send('test')
.assertReply('You said test')
@ -49,7 +52,7 @@ describe('ActivityPrompt', function () {
});
it('should re-prompt with original prompt if validator returned false.', async function () {
const adapter = new TestAdapter(async turnContext => {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.continueDialog();
@ -65,13 +68,16 @@ describe('ActivityPrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new SimpleActivityPrompt('prompt', async prompt => {
assert(prompt, `validator missing PromptValidatorContext.`);
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
return false;
}));
dialogs.add(
new SimpleActivityPrompt('prompt', async (prompt) => {
assert(prompt, 'validator missing PromptValidatorContext.');
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
return false;
})
);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please send an activity.')
.send('test')
.assertReply('Please send an activity.')
@ -79,7 +85,7 @@ describe('ActivityPrompt', function () {
});
it('should re-prompt with custom retryPrompt if validator returned false.', async function () {
const adapter = new TestAdapter(async turnContext => {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.continueDialog();
@ -95,36 +101,41 @@ describe('ActivityPrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new SimpleActivityPrompt('prompt', async prompt => {
assert(prompt, `validator missing PromptValidatorContext.`);
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
return false;
}));
dialogs.add(
new SimpleActivityPrompt('prompt', async (prompt) => {
assert(prompt, 'validator missing PromptValidatorContext.');
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
return false;
})
);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please send activity.')
.send('test')
.assertReply('Activity not received.')
.startTest();
});
it('should see attemptCount increment.', async function() {
it('should see attemptCount increment.', async function () {
const convoState = new ConversationState(new MemoryStorage());
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new SimpleActivityPrompt('prompt', async prompt => {
assert(prompt, `validator missing PromptValidatorContext.`);
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
if (prompt.recognized.value.type !== ActivityTypes.Event) {
prompt.context.sendActivity(`attemptCount ${ prompt.attemptCount }`);
return false;
}
return true;
}));
const adapter = new TestAdapter(async turnContext => {
dialogs.add(
new SimpleActivityPrompt('prompt', async (prompt) => {
assert(prompt, 'validator missing PromptValidatorContext.');
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
if (prompt.recognized.value.type !== ActivityTypes.Event) {
prompt.context.sendActivity(`attemptCount ${prompt.attemptCount}`);
return false;
}
return true;
})
);
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.continueDialog();
@ -132,12 +143,13 @@ describe('ActivityPrompt', function () {
await dc.prompt('prompt', { prompt: 'Please send activity.', retryPrompt: 'Activity not received.' });
} else if (results.status === DialogTurnStatus.complete) {
const reply = results.result.type;
await turnContext.sendActivity(`You sent a(n) ${ reply }`);
await turnContext.sendActivity(`You sent a(n) ${reply}`);
}
await convoState.saveChanges(turnContext);
});
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please send activity.')
.send('100')
.assertReply('attemptCount 1')
@ -146,7 +158,7 @@ describe('ActivityPrompt', function () {
.send('300')
.assertReply('attemptCount 3')
.send({ type: ActivityTypes.Event })
.assertReply(`You sent a(n) ${ ActivityTypes.Event }`)
.assertReply(`You sent a(n) ${ActivityTypes.Event}`)
.send('Another!')
.assertReply('Please send activity.')
.send('100')
@ -156,11 +168,11 @@ describe('ActivityPrompt', function () {
.send('300')
.assertReply('attemptCount 3')
.send({ type: ActivityTypes.Event })
.assertReply(`You sent a(n) ${ ActivityTypes.Event }`)
.assertReply(`You sent a(n) ${ActivityTypes.Event}`)
.startTest();
});
it('should not have resumeDialog() use the retry prompt.', async function() {
it('should not have resumeDialog() use the retry prompt.', async function () {
const convoState = new ConversationState(new MemoryStorage());
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
@ -172,28 +184,30 @@ describe('ActivityPrompt', function () {
const dc = await dialogs.createContext(turnContext);
switch (turnContext.activity.text) {
case 'begin':
case 'begin': {
const options = {
prompt: 'please send an event.',
retryPrompt: 'Retrying - please send an event.'
retryPrompt: 'Retrying - please send an event.',
};
await dc.prompt('prompt', options);
break;
case 'continue':
}
case 'continue': {
await prompt.continueDialog(dc);
break;
case 'resume':
}
case 'resume': {
await prompt.resumeDialog(dc, DialogReason.nextCalled);
break;
}
}
await convoState.saveChanges(turnContext);
});
await adapter.send('begin')
await adapter
.send('begin')
.assertReply('please send an event.')
.send('continue')
.assertReply('Retrying - please send an event.')

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

@ -3,11 +3,11 @@ const { AttachmentPrompt, DialogSet, DialogTurnStatus } = require('../');
const assert = require('assert');
const answerMessage = {
text: `here you go`,
text: 'here you go',
type: 'message',
attachments: [{ contentType: 'test', content: 'test1' }],
};
const invalidMessage = { text: `what?`, type: 'message' };
const invalidMessage = { text: 'what?', type: 'message' };
describe('AttachmentPrompt', function () {
this.timeout(5000);

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

@ -3,8 +3,8 @@ const { ChoicePrompt, ChoiceFactory, DialogSet, ListStyle, DialogTurnStatus } =
const { PromptCultureModels } = require('../');
const assert = require('assert');
const answerMessage = { text: `red`, type: 'message' };
const invalidMessage = { text: `purple`, type: 'message' };
const answerMessage = { text: 'red', type: 'message' };
const invalidMessage = { text: 'purple', type: 'message' };
const stringChoices = ['red', 'green', 'blue'];
@ -292,7 +292,7 @@ describe('ChoicePrompt', function () {
await adapter
.send({ text: 'Hello', type: ActivityTypes.Message, locale: undefined })
.assertReply((activity) => {
.assertReply(() => {
assert('Please choose a color. (1) red, (2) green, o (3) blue');
})
.send(invalidMessage)

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

@ -57,13 +57,13 @@ describe('channel methods', function () {
assert.strictEqual(supportsCardActions(Channels.Skype, 5), false);
});
it('should return true for supportsCardActions() with teams and 50', function (){
it('should return true for supportsCardActions() with teams and 50', function () {
assert.strictEqual(supportsCardActions(Channels.Msteams, 50), true);
})
});
it('should return false for supportsCardActions() with teams and 51', function (){
it('should return false for supportsCardActions() with teams and 51', function () {
assert.strictEqual(supportsCardActions(Channels.Msteams, 51), false);
})
});
it('should return the channelId from context.activity.', function () {
assert.strictEqual(getChannelId({ activity: { channelId: Channels.Facebook } }), Channels.Facebook);

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

@ -121,21 +121,21 @@ describe('The ChoiceFactory', function () {
it('should render choices inline.', function () {
const activity = ChoiceFactory.inline(colorChoices, 'select from:');
assertActivity(activity, {
text: `select from: (1) red, (2) green, or (3) blue`,
text: 'select from: (1) red, (2) green, or (3) blue',
});
});
it('should render choices as a list.', function () {
const activity = ChoiceFactory.list(colorChoices, 'select from:');
assertActivity(activity, {
text: `select from:\n\n 1. red\n 2. green\n 3. blue`,
text: 'select from:\n\n 1. red\n 2. green\n 3. blue',
});
});
it('should render choices as suggested actions.', function () {
const activity = ChoiceFactory.suggestedAction(colorChoices, 'select from:');
assertActivity(activity, {
text: `select from:`,
text: 'select from:',
suggestedActions: {
actions: [
{ type: 'imBack', value: 'red', title: 'red' },
@ -204,7 +204,7 @@ describe('The ChoiceFactory', function () {
it('should automatically choose render style based on channel type.', function () {
const activity = ChoiceFactory.forChannel('emulator', colorChoices, 'select from:');
assertActivity(activity, {
text: `select from:`,
text: 'select from:',
suggestedActions: {
actions: [
{ type: 'imBack', value: 'red', title: 'red' },

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

@ -63,21 +63,21 @@ describe('findValues()', function () {
this.timeout(5000);
it('should find a simple value in an single word utterance.', function () {
const found = findValues(`red`, colorValues);
const found = findValues('red', colorValues);
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 0, 2, 'red');
assertValue(found[0], 'red', 0, 1.0);
});
it('should find a simple value in an utterance.', function () {
const found = findValues(`the red one please.`, colorValues);
const found = findValues('the red one please.', colorValues);
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 4, 6, 'red');
assertValue(found[0], 'red', 0, 1.0);
});
it('should find multiple values within an utterance.', function () {
const found = findValues(`the red and blue ones please.`, colorValues);
const found = findValues('the red and blue ones please.', colorValues);
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 4, 6, 'red');
assertValue(found[0], 'red', 0, 1.0);
@ -85,7 +85,7 @@ describe('findValues()', function () {
});
it('should find multiple values that overlap.', function () {
const found = findValues(`the bread pudding and bread please.`, overlappingValues);
const found = findValues('the bread pudding and bread please.', overlappingValues);
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 4, 16, 'bread pudding');
assertValue(found[0], 'bread pudding', 1, 1.0);
@ -93,7 +93,7 @@ describe('findValues()', function () {
});
it('should correctly disambiguate between very similar values.', function () {
const found = findValues(`option B`, similarValues, { allowPartialMatches: true });
const found = findValues('option B', similarValues, { allowPartialMatches: true });
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
assertValue(found[0], 'option B', 1, 1.0);
});
@ -118,14 +118,14 @@ describe('findChoices()', function () {
this.timeout(5000);
it('should find a single choice in an utterance.', function () {
const found = findChoices(`the red one please.`, colorChoices);
const found = findChoices('the red one please.', colorChoices);
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 4, 6, 'red');
assertChoice(found[0], 'red', 0, 1.0, 'red');
});
it('should find multiple choices within an utterance.', function () {
const found = findChoices(`the red and blue ones please.`, colorChoices);
const found = findChoices('the red and blue ones please.', colorChoices);
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 4, 6, 'red');
assertChoice(found[0], 'red', 0, 1.0);
@ -133,7 +133,7 @@ describe('findChoices()', function () {
});
it('should find multiple choices that overlap.', function () {
const found = findChoices(`the bread pudding and bread please.`, overlappingChoices);
const found = findChoices('the bread pudding and bread please.', overlappingChoices);
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 4, 16, 'bread pudding');
assertChoice(found[0], 'bread pudding', 1, 1.0);
@ -149,59 +149,59 @@ describe('recognizeChoices()', function () {
this.timeout(5000);
it('should find a choice in an utterance by name.', function () {
const found = recognizeChoices(`the red one please.`, colorChoices);
const found = recognizeChoices('the red one please.', colorChoices);
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 4, 6, 'red');
assertChoice(found[0], 'red', 0, 1.0, 'red');
});
it('should find a choice in an utterance by ordinal position.', function () {
const found = recognizeChoices(`the first one please.`, colorChoices);
const found = recognizeChoices('the first one please.', colorChoices);
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 4, 8, 'first');
assertChoice(found[0], 'red', 0, 1.0);
});
it('should find multiple choices in an utterance by ordinal position.', function () {
const found = recognizeChoices(`the first and third one please.`, colorChoices);
const found = recognizeChoices('the first and third one please.', colorChoices);
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
assertChoice(found[0], 'red', 0, 1.0);
assertChoice(found[1], 'blue', 2, 1.0);
});
it('should find a choice in an utterance by numerical index (as digit.)', function () {
const found = recognizeChoices(`1`, colorChoices);
const found = recognizeChoices('1', colorChoices);
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 0, 0, '1');
assertChoice(found[0], 'red', 0, 1.0);
});
it('should find a choice in an utterance by numerical index (as text.)', function () {
const found = recognizeChoices(`one`, colorChoices);
const found = recognizeChoices('one', colorChoices);
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
assertResult(found[0], 0, 2, 'one');
assertChoice(found[0], 'red', 0, 1.0);
});
it('should find multiple choices in an utterance by numerical index.', function () {
const found = recognizeChoices(`option one and 3.`, colorChoices);
const found = recognizeChoices('option one and 3.', colorChoices);
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
assertChoice(found[0], 'red', 0, 1.0);
assertChoice(found[1], 'blue', 2, 1.0);
});
it('should not find a choice if recognizeOrdinals option disabled.', function () {
const found = recognizeChoices(`first`, colorChoices, { recognizeOrdinals: false });
const found = recognizeChoices('first', colorChoices, { recognizeOrdinals: false });
assert(found.length === 0, `Invalid token count of '${found.length}' returned.`);
});
it('should not find a choice if recognizeNumbers option disabled.', function () {
const found = recognizeChoices(`1`, colorChoices, { recognizeNumbers: false });
const found = recognizeChoices('1', colorChoices, { recognizeNumbers: false });
assert(found.length === 0, `Invalid token count of '${found.length}' returned.`);
});
it('should not find a choice if both recognizeOrdinals and recognizeNumbers options are disabled.', function () {
const found = recognizeChoices(`the first and third one please.`, colorChoices, {
const found = recognizeChoices('the first and third one please.', colorChoices, {
recognizeOrdinals: false,
recognizeNumbers: false,
});

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

@ -15,7 +15,7 @@ describe('defaultTokenizer()', function () {
this.timeout(5000);
it('should break on spaces.', function () {
const tokens = defaultTokenizer(`how now brown cow`);
const tokens = defaultTokenizer('how now brown cow');
assert(tokens.length === 4);
assertToken(tokens[0], 0, 2, 'how');
assertToken(tokens[1], 4, 6, 'now');
@ -24,7 +24,7 @@ describe('defaultTokenizer()', function () {
});
it('should break on punctuation.', function () {
const tokens = defaultTokenizer(`how-now.brown:cow?`);
const tokens = defaultTokenizer('how-now.brown:cow?');
assert(tokens.length === 4);
assertToken(tokens[0], 0, 2, 'how');
assertToken(tokens[1], 4, 6, 'now');
@ -33,7 +33,7 @@ describe('defaultTokenizer()', function () {
});
it('should tokenize single character tokens.', function () {
const tokens = defaultTokenizer(`a b c d`);
const tokens = defaultTokenizer('a b c d');
assert(tokens.length === 4);
assertToken(tokens[0], 0, 0, 'a');
assertToken(tokens[1], 2, 2, 'b');
@ -42,24 +42,24 @@ describe('defaultTokenizer()', function () {
});
it('should return a single token.', function () {
const tokens = defaultTokenizer(`food`);
const tokens = defaultTokenizer('food');
assert(tokens.length === 1);
assertToken(tokens[0], 0, 3, 'food');
});
it('should return no tokens.', function () {
const tokens = defaultTokenizer(`.?;-()`);
const tokens = defaultTokenizer('.?;-()');
assert(tokens.length === 0);
});
it('should return a the normalized and original text for a token.', function () {
const tokens = defaultTokenizer(`fOoD`);
const tokens = defaultTokenizer('fOoD');
assert(tokens.length === 1);
assertToken(tokens[0], 0, 3, 'fOoD', 'food');
});
it('should break on emojis.', function () {
const tokens = defaultTokenizer(`food 💥👍😀`);
const tokens = defaultTokenizer('food 💥👍😀');
assert(tokens.length === 4);
assertToken(tokens[0], 0, 3, 'food');
assertToken(tokens[1], 5, 6, '💥');

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

@ -1,23 +1,31 @@
const { ConversationState, MemoryStorage, TestAdapter, Severity } = require('botbuilder-core');
const { Dialog, DialogReason, DialogSet, DialogTurnStatus, DialogContextError, ComponentDialog, WaterfallDialog } = require('../');
const {
Dialog,
DialogReason,
DialogSet,
DialogTurnStatus,
DialogContextError,
ComponentDialog,
WaterfallDialog,
} = require('../');
const assert = require('assert');
function simpleStepContextCheck(step) {
assert(step, `step not found.`);
assert(typeof step === 'object', `step is not a WaterfallStepContext.`);
assert(step, 'step not found.');
assert(typeof step === 'object', 'step is not a WaterfallStepContext.');
}
describe('ComponentDialog', function () {
this.timeout(5000);
it('should set initial dialog to be first dialog added via addDialog()', function () {
const simpleWaterfall = new WaterfallDialog('simpleWaterfall', [async (step) => {}]);
const simpleWaterfall = new WaterfallDialog('simpleWaterfall', [async () => {}]);
const simpleH2ofall = new WaterfallDialog('simpleH2ofall', [async (step) => {}]);
const simpleH2ofall = new WaterfallDialog('simpleH2ofall', [async () => {}]);
const component = new ComponentDialog('component');
component.addDialog(simpleWaterfall);
assert(component.initialDialogId === 'simpleWaterfall', `unexpected initialDialogId`);
assert(component.initialDialogId === 'simpleWaterfall', 'unexpected initialDialogId');
component.addDialog(simpleH2ofall);
assert(
component.initialDialogId === 'simpleWaterfall',
@ -101,7 +109,7 @@ describe('ComponentDialog', function () {
await adapter.send('Hi').startTest();
});
it(`should return Dialog.EndOfTurn if the dialog's turnResult.status === 'waiting'.`, async function () {
it("should return Dialog.EndOfTurn if the dialog's turnResult.status === 'waiting'.", async function () {
const conversationState = new ConversationState(new MemoryStorage());
const dialogState = conversationState.createProperty('dialog');
@ -135,12 +143,12 @@ describe('ComponentDialog', function () {
});
it('should return any found dialogs.', function () {
const simpleWaterfall = new WaterfallDialog('simpleWaterfall', [async (step) => {}]);
const simpleWaterfall = new WaterfallDialog('simpleWaterfall', [async () => {}]);
const component = new ComponentDialog('component');
component.addDialog(simpleWaterfall);
const dialog = component.findDialog('simpleWaterfall');
assert(dialog === simpleWaterfall, `unexpected dialog returned`);
assert(dialog === simpleWaterfall, 'unexpected dialog returned');
});
it('should return undefined for not found dialogs.', function () {
@ -383,7 +391,7 @@ describe('ComponentDialog', function () {
const dialogs = new DialogSet(dialogState);
dialogs.add(component);
dialogs.telemetryClient = {
trackEvent: function (telemetry) {},
trackEvent: function () {},
trackTrace: function (telemetry) {
if (telemetry.severityLevel === Severity.Warning) {
assert.equal(telemetry.message, 'Unhandled dialog event: versionChanged. Active Dialog: test');

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

@ -2,9 +2,7 @@ const { ActivityTypes, ConversationState, MemoryStorage, TestAdapter } = require
const { ConfirmPrompt, DialogSet, DialogTurnStatus, ListStyle } = require('../');
const assert = require('assert');
const beginMessage = { text: `begin`, type: 'message' };
const answerMessage = { text: `yes`, type: 'message' };
const invalidMessage = { text: `what?`, type: 'message' };
const invalidMessage = { text: 'what?', type: 'message' };
describe('ConfirmPrompt', function () {
this.timeout(5000);
@ -18,7 +16,7 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', { prompt: 'Please confirm.' });
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -31,10 +29,11 @@ describe('ConfirmPrompt', function () {
const dialogs = new DialogSet(dialogState);
dialogs.add(new ConfirmPrompt('prompt'));
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. (1) Yes or (2) No')
.send('yes')
.assertReply(`The result found is 'true'.`)
.assertReply("The result found is 'true'.")
.startTest();
});
@ -46,7 +45,7 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', { prompt: 'Please confirm. Yes or No' });
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -56,16 +55,17 @@ describe('ConfirmPrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
assert(prompt, `PromptValidatorContext not found.`);
assert(prompt, 'PromptValidatorContext not found.');
return prompt.recognized.succeeded;
});
confirmPrompt.style = ListStyle.none;
dialogs.add(confirmPrompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. Yes or No')
.send('no')
.assertReply(`The result found is 'false'.`)
.assertReply("The result found is 'false'.")
.startTest();
});
@ -77,10 +77,10 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: 'Please confirm. Yes or No',
retryPrompt: `Please reply with 'Yes' or 'No'.`
retryPrompt: "Please reply with 'Yes' or 'No'.",
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -93,13 +93,13 @@ describe('ConfirmPrompt', function () {
confirmPrompt.style = ListStyle.none;
dialogs.add(confirmPrompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. Yes or No')
.send('what?')
.assertReply(`Please reply with 'Yes' or 'No'.`)
.assertReply("Please reply with 'Yes' or 'No'.")
.send('no')
.assertReply(`The result found is 'false'.`)
.assertReply("The result found is 'false'.")
.startTest();
});
@ -111,10 +111,10 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: 'Please confirm. Yes or No',
retryPrompt: `Please reply with 'Yes' or 'No'.`
retryPrompt: "Please reply with 'Yes' or 'No'.",
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -124,18 +124,19 @@ describe('ConfirmPrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
assert(prompt, `PromptValidatorContext not found.`);
assert(prompt, 'PromptValidatorContext not found.');
return prompt.recognized.succeeded;
});
confirmPrompt.style = ListStyle.none;
dialogs.add(confirmPrompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. Yes or No')
.send('what?')
.assertReply(`Please reply with 'Yes' or 'No'.`)
.assertReply("Please reply with 'Yes' or 'No'.")
.send('no')
.assertReply(`The result found is 'false'.`)
.assertReply("The result found is 'false'.")
.startTest();
});
@ -147,10 +148,10 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: 'Please confirm. Yes or No',
retryPrompt: `Please reply with 'Yes' or 'No'.`
retryPrompt: "Please reply with 'Yes' or 'No'.",
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -160,22 +161,22 @@ describe('ConfirmPrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
assert(prompt, `PromptValidatorContext not found.`);
assert(prompt, 'PromptValidatorContext not found.');
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('The correct response is either yes or no. Please choose one.')
await prompt.context.sendActivity('The correct response is either yes or no. Please choose one.');
}
return prompt.recognized.succeeded;
});
confirmPrompt.style = ListStyle.none;
dialogs.add(confirmPrompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. Yes or No')
.send('what?')
.assertReply('The correct response is either yes or no. Please choose one.')
.send('no')
.assertReply(`The result found is 'false'.`)
.assertReply("The result found is 'false'.")
.startTest();
});
@ -187,7 +188,7 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.beginDialog('prompt');
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -200,13 +201,13 @@ describe('ConfirmPrompt', function () {
confirmPrompt.style = ListStyle.none;
dialogs.add(confirmPrompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('')
.send('what?')
.assertReply('')
.send('no')
.assertReply(`The result found is 'false'.`)
.assertReply("The result found is 'false'.")
.startTest();
});
@ -218,10 +219,10 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: 'Please confirm. Yes or No',
retryPrompt: `Please reply with 'Yes' or 'No'.`
retryPrompt: "Please reply with 'Yes' or 'No'.",
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -234,13 +235,13 @@ describe('ConfirmPrompt', function () {
confirmPrompt.style = ListStyle.none;
dialogs.add(confirmPrompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. Yes or No')
.send({ type: ActivityTypes.Message, attachments: ['ignoreThis']})
.assertReply(`Please reply with 'Yes' or 'No'.`)
.send({ type: ActivityTypes.Message, attachments: ['ignoreThis'] })
.assertReply("Please reply with 'Yes' or 'No'.")
.send('no')
.assertReply(`The result found is 'false'.`)
.assertReply("The result found is 'false'.")
.startTest();
});
@ -252,10 +253,10 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: 'Please confirm. Yes or No',
retryPrompt: `Please reply with 'Yes' or 'No'.`
retryPrompt: "Please reply with 'Yes' or 'No'.",
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -268,15 +269,15 @@ describe('ConfirmPrompt', function () {
confirmPrompt.style = ListStyle.none;
dialogs.add(confirmPrompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. Yes or No')
.send('')
.assertReply('Please reply with \'Yes\' or \'No\'.')
.assertReply("Please reply with 'Yes' or 'No'.")
.send({ type: ActivityTypes.Message, text: null })
.assertReply('Please reply with \'Yes\' or \'No\'.')
.assertReply("Please reply with 'Yes' or 'No'.")
.send('no')
.assertReply(`The result found is 'false'.`)
.assertReply("The result found is 'false'.")
.startTest();
});
@ -301,16 +302,21 @@ describe('ConfirmPrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('bad input.');
}
return prompt.recognized.succeeded;
}, 'ja-jp');
const confirmPrompt = new ConfirmPrompt(
'prompt',
async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('bad input.');
}
return prompt.recognized.succeeded;
},
'ja-jp'
);
dialogs.add(confirmPrompt);
await adapter.send({ text: 'Hello', type: ActivityTypes.Message })
await adapter
.send({ text: 'Hello', type: ActivityTypes.Message })
.assertReply('Please confirm. (1) はい または (2) いいえ')
.send(invalidMessage)
.assertReply('bad input.')
@ -349,7 +355,8 @@ describe('ConfirmPrompt', function () {
});
dialogs.add(confirmPrompt);
await adapter.send({ text: 'Hello', type: ActivityTypes.Message, locale: 'ja-jp' })
await adapter
.send({ text: 'Hello', type: ActivityTypes.Message, locale: 'ja-jp' })
.assertReply('Please confirm. (1) はい または (2) いいえ')
.send({ text: 'いいえ', type: ActivityTypes.Message, locale: 'ja-jp' })
.assertReply('false')
@ -377,16 +384,21 @@ describe('ConfirmPrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('bad input.');
}
return prompt.recognized.succeeded;
}, 'es-es');
const confirmPrompt = new ConfirmPrompt(
'prompt',
async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('bad input.');
}
return prompt.recognized.succeeded;
},
'es-es'
);
dialogs.add(confirmPrompt);
await adapter.send({ text: 'Hello', type: ActivityTypes.Message, locale: 'ja-jp' })
await adapter
.send({ text: 'Hello', type: ActivityTypes.Message, locale: 'ja-jp' })
.assertReply('Please confirm. (1) はい または (2) いいえ')
.send({ text: 'いいえ', type: ActivityTypes.Message, locale: 'ja-jp' })
.assertReply('false')
@ -394,20 +406,10 @@ describe('ConfirmPrompt', function () {
});
it('should recognize locale variations of correct locales', async function () {
const locales = [
'es-es',
'nl-nl',
'en-us',
'fr-fr',
'de-de',
'ja-jp',
'it-it',
'pt-br',
'zh-cn'
];
const locales = ['es-es', 'nl-nl', 'en-us', 'fr-fr', 'de-de', 'ja-jp', 'it-it', 'pt-br', 'zh-cn'];
// es-ES
const capEnding = (locale) => {
return `${ locale.split('-')[0] }-${ locale.split('-')[1].toUpperCase() }`;
return `${locale.split('-')[0]}-${locale.split('-')[1].toUpperCase()}`;
};
// es-Es
const titleEnding = (locale) => {
@ -430,61 +432,70 @@ describe('ConfirmPrompt', function () {
capEnding(locale),
titleEnding(locale),
capTwoLetter(locale),
lowerTwoLetter(locale)
lowerTwoLetter(locale),
];
return obj;
}, {});
// Test each valid locale
await Promise.all(Object.keys(localeTests).map(async (validLocale) => {
// Hold the correct answer from when a valid locale is used
let expectedAnswer;
// Test each of the test locales
await Promise.all(localeTests[validLocale].map(async (testLocale) => {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.continueDialog();
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', { prompt: 'Please confirm.' });
} else if (results.status === DialogTurnStatus.complete) {
const confirmed = results.result;
if (confirmed) {
await turnContext.sendActivity('true');
} else {
await turnContext.sendActivity('false');
}
}
await convoState.saveChanges(turnContext);
});
const convoState = new ConversationState(new MemoryStorage());
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('bad input.');
}
return prompt.recognized.succeeded;
}, testLocale);
dialogs.add(confirmPrompt);
await adapter.send({ text: 'Hello', type: ActivityTypes.Message, locale: testLocale })
.assertReply((activity) => {
// if the valid locale is tested, save the answer because then we can test to see
// if the test locales produce the same answer
if (validLocale === testLocale) {
expectedAnswer = activity.text;
}
assert.strictEqual(activity.text, expectedAnswer);
await Promise.all(
Object.keys(localeTests).map(async (validLocale) => {
// Hold the correct answer from when a valid locale is used
let expectedAnswer;
// Test each of the test locales
await Promise.all(
localeTests[validLocale].map(async (testLocale) => {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.continueDialog();
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', { prompt: 'Please confirm.' });
} else if (results.status === DialogTurnStatus.complete) {
const confirmed = results.result;
if (confirmed) {
await turnContext.sendActivity('true');
} else {
await turnContext.sendActivity('false');
}
}
await convoState.saveChanges(turnContext);
});
const convoState = new ConversationState(new MemoryStorage());
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
const confirmPrompt = new ConfirmPrompt(
'prompt',
async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('bad input.');
}
return prompt.recognized.succeeded;
},
testLocale
);
dialogs.add(confirmPrompt);
await adapter
.send({ text: 'Hello', type: ActivityTypes.Message, locale: testLocale })
.assertReply((activity) => {
// if the valid locale is tested, save the answer because then we can test to see
// if the test locales produce the same answer
if (validLocale === testLocale) {
expectedAnswer = activity.text;
}
assert.strictEqual(activity.text, expectedAnswer);
})
.startTest();
})
.startTest();
}));
}));
);
})
);
});
it('should accept and recognize custom locale dict', async function() {
it('should accept and recognize custom locale dict', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
@ -509,7 +520,7 @@ describe('ConfirmPrompt', function () {
locale: 'custom-custom',
separator: 'customSeparator',
noInLanguage: 'customNo',
yesInLanguage: 'customYes'
yesInLanguage: 'customYes',
};
const customDict = {
@ -519,23 +530,29 @@ describe('ConfirmPrompt', function () {
inlineSeparator: culture.separator,
inlineOr: culture.inlineOr,
inlineOrMore: culture.inlineOrMore,
includeNumbers: true
}
}
includeNumbers: true,
},
},
};
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('bad input.');
}
return prompt.recognized.succeeded;
}, culture.locale, customDict);
const confirmPrompt = new ConfirmPrompt(
'prompt',
async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('bad input.');
}
return prompt.recognized.succeeded;
},
culture.locale,
customDict
);
dialogs.add(confirmPrompt);
await adapter.send({ text: 'Hello', type: ActivityTypes.Message, locale: culture.locale })
await adapter
.send({ text: 'Hello', type: ActivityTypes.Message, locale: culture.locale })
.assertReply('Please confirm. (1) customYes customOr (2) customNo')
.send('customYes')
.assertReply('true')
@ -550,7 +567,7 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt');
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -563,12 +580,13 @@ describe('ConfirmPrompt', function () {
prompt.choiceOptions = { includeNumbers: true };
dialogs.add(prompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply(' (1) Yes or (2) No')
.send('lala')
.assertReply(' (1) Yes or (2) No')
.send('yes')
.assertReply(`The result found is 'true'.`)
.assertReply("The result found is 'true'.")
.startTest();
});
@ -580,10 +598,13 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
retryPrompt: {
text: 'Please confirm, say "yes" or "no" or something like that.',
type: ActivityTypes.Message,
},
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -596,18 +617,18 @@ describe('ConfirmPrompt', function () {
prompt.choiceOptions = { includeNumbers: true };
dialogs.add(prompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. (1) Yes or (2) No')
.send('lala')
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
.send('1')
.assertReply(`The result found is 'true'.`)
.assertReply("The result found is 'true'.")
.startTest();
});
it('should recognize valid number and default to en if locale is null.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
turnContext.activity.locale = null;
const dc = await dialogs.createContext(turnContext);
@ -616,10 +637,13 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
retryPrompt: {
text: 'Please confirm, say "yes" or "no" or something like that.',
type: ActivityTypes.Message,
},
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -632,18 +656,18 @@ describe('ConfirmPrompt', function () {
prompt.choiceOptions = { includeNumbers: true };
dialogs.add(prompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. (1) Yes or (2) No')
.send('lala')
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
.send('1')
.assertReply(`The result found is 'true'.`)
.assertReply("The result found is 'true'.")
.startTest();
});
it('should recognize valid number and default to en if locale invalid string.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
turnContext.activity.locale = 'invalid-locale';
const dc = await dialogs.createContext(turnContext);
@ -652,10 +676,13 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
retryPrompt: {
text: 'Please confirm, say "yes" or "no" or something like that.',
type: ActivityTypes.Message,
},
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -668,28 +695,31 @@ describe('ConfirmPrompt', function () {
prompt.choiceOptions = { includeNumbers: true };
dialogs.add(prompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. (1) Yes or (2) No')
.send('lala')
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
.send('1')
.assertReply(`The result found is 'true'.`)
.assertReply("The result found is 'true'.")
.startTest();
});
it('should recognize valid number and default to en if defaultLocale invalid string.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.continueDialog();
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
retryPrompt: {
text: 'Please confirm, say "yes" or "no" or something like that.',
type: ActivityTypes.Message,
},
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -702,15 +732,16 @@ describe('ConfirmPrompt', function () {
prompt.choiceOptions = { includeNumbers: true };
dialogs.add(prompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. (1) Yes or (2) No')
.send('lala')
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
.send('1')
.assertReply(`The result found is 'true'.`)
.assertReply("The result found is 'true'.")
.startTest();
});
it('should not recognize invalid number when choiceOptions.includeNumbers is true.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
@ -719,10 +750,13 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
retryPrompt: {
text: 'Please confirm, say "yes" or "no" or something like that.',
type: ActivityTypes.Message,
},
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -735,12 +769,13 @@ describe('ConfirmPrompt', function () {
prompt.choiceOptions = { includeNumbers: true };
dialogs.add(prompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. (1) Yes or (2) No')
.send('400')
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
.send('1')
.assertReply(`The result found is 'true'.`)
.assertReply("The result found is 'true'.")
.startTest();
});
@ -752,10 +787,13 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
retryPrompt: {
text: 'Please confirm, say "yes" or "no" or something like that.',
type: ActivityTypes.Message,
},
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -768,12 +806,13 @@ describe('ConfirmPrompt', function () {
prompt.choiceOptions = { includeNumbers: false, inlineSeparator: '~' };
dialogs.add(prompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. Yes or No')
.send('1')
.assertReply('Please confirm, say "yes" or "no" or something like that. Yes or No')
.send('no')
.assertReply(`The result found is 'false'.`)
.assertReply("The result found is 'false'.")
.startTest();
});
@ -785,10 +824,13 @@ describe('ConfirmPrompt', function () {
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', {
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
retryPrompt: {
text: 'Please confirm, say "yes" or "no" or something like that.',
type: ActivityTypes.Message,
},
});
} else if (results.status === DialogTurnStatus.complete) {
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
await turnContext.sendActivity(`The result found is '${results.result}'.`);
}
await convoState.saveChanges(turnContext);
});
@ -801,12 +843,13 @@ describe('ConfirmPrompt', function () {
prompt.choiceOptions = { includeNumbers: undefined };
dialogs.add(prompt);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please confirm. Yes or No')
.send('lala')
.assertReply('Please confirm, say "yes" or "no" or something like that. Yes or No')
.send('1')
.assertReply(`The result found is 'true'.`)
.assertReply("The result found is 'true'.")
.startTest();
});
});

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

@ -2,9 +2,9 @@ const { ActivityTypes, ConversationState, MemoryStorage, TestAdapter } = require
const { DateTimePrompt, DialogSet, DialogTurnStatus } = require('../');
const assert = require('assert');
const answerMessage = { text: `January 1st, 2018 at 9am`, type: ActivityTypes.Message };
const answerMessage2 = { text: `September 2nd, 2012`, type: ActivityTypes.Message };
const invalidMessage = { text: `I am not sure`, type: ActivityTypes.Message };
const answerMessage = { text: 'January 1st, 2018 at 9am', type: ActivityTypes.Message };
const answerMessage2 = { text: 'September 2nd, 2012', type: ActivityTypes.Message };
const invalidMessage = { text: 'I am not sure', type: ActivityTypes.Message };
describe('DatetimePrompt', function () {
this.timeout(5000);
@ -31,7 +31,8 @@ describe('DatetimePrompt', function () {
const dialogs = new DialogSet(dialogState);
dialogs.add(new DateTimePrompt('prompt'));
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please say something.')
.send(answerMessage)
.assertReply('2018-01-01T09')
@ -57,7 +58,8 @@ describe('DatetimePrompt', function () {
const dialogs = new DialogSet(dialogState);
dialogs.add(new DateTimePrompt('prompt'));
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please say something.')
.send(answerMessage)
.assertReply('2018-01-01T09')
@ -82,12 +84,15 @@ describe('DatetimePrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new DateTimePrompt('prompt', async (prompt) => {
assert(prompt);
return prompt.recognized.succeeded;
}));
dialogs.add(
new DateTimePrompt('prompt', async (prompt) => {
assert(prompt);
return prompt.recognized.succeeded;
})
);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please say something.')
.send(answerMessage)
.assertReply('2018-01-01T09')
@ -100,7 +105,10 @@ describe('DatetimePrompt', function () {
const results = await dc.continueDialog();
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', { prompt: 'Please say something.', retryPrompt: 'Please provide a valid datetime.' });
await dc.prompt('prompt', {
prompt: 'Please say something.',
retryPrompt: 'Please provide a valid datetime.',
});
} else if (results.status === DialogTurnStatus.complete) {
const dates = results.result;
await turnContext.sendActivity(dates[0].timex);
@ -112,12 +120,15 @@ describe('DatetimePrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new DateTimePrompt('prompt', async (prompt) => {
assert(prompt);
return prompt.recognized.succeeded;
}));
dialogs.add(
new DateTimePrompt('prompt', async (prompt) => {
assert(prompt);
return prompt.recognized.succeeded;
})
);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please say something.')
.send(invalidMessage)
.assertReply('Please provide a valid datetime.')
@ -132,7 +143,10 @@ describe('DatetimePrompt', function () {
const results = await dc.continueDialog();
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', { prompt: 'Please say something.', retryPrompt: 'Please provide a valid datetime.' });
await dc.prompt('prompt', {
prompt: 'Please say something.',
retryPrompt: 'Please provide a valid datetime.',
});
} else if (results.status === DialogTurnStatus.complete) {
const dates = results.result;
await turnContext.sendActivity(dates[0].timex);
@ -144,15 +158,18 @@ describe('DatetimePrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new DateTimePrompt('prompt', async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('That was a bad date.');
}
return prompt.recognized.succeeded;
}));
dialogs.add(
new DateTimePrompt('prompt', async (prompt) => {
assert(prompt);
if (!prompt.recognized.succeeded) {
await prompt.context.sendActivity('That was a bad date.');
}
return prompt.recognized.succeeded;
})
);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please say something.')
.send(invalidMessage)
.assertReply('That was a bad date.')
@ -179,16 +196,14 @@ describe('DatetimePrompt', function () {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new DateTimePrompt('prompt', async (prompt) => {
assert(prompt);
return prompt.recognized.succeeded;
}));
dialogs.add(
new DateTimePrompt('prompt', async (prompt) => {
assert(prompt);
return prompt.recognized.succeeded;
})
);
await adapter.send('Hello')
.send(invalidMessage)
.send(answerMessage2)
.assertReply('2012-09-02')
.startTest();
await adapter.send('Hello').send(invalidMessage).send(answerMessage2).assertReply('2012-09-02').startTest();
});
it('should not recognize, then re-prompt without error for falsy input.', async function () {
@ -213,7 +228,8 @@ describe('DatetimePrompt', function () {
const dialogs = new DialogSet(dialogState);
dialogs.add(new DateTimePrompt('prompt'));
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Enter a date.')
.send('')
.assertReply('Enter a date.')

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

@ -2,7 +2,7 @@ const { ConversationState, MemoryStorage, TestAdapter } = require('botbuilder-co
const { DialogSet, Dialog, DialogTurnStatus } = require('../');
const assert = require('assert');
const beginMessage = { text: `begin`, type: 'message' };
const beginMessage = { text: 'begin', type: 'message' };
class TestDialog extends Dialog {
constructor(dialogId) {
@ -20,7 +20,7 @@ class TestDialog extends Dialog {
return Dialog.EndOfTurn;
}
async continueDialog(dc, options) {
async continueDialog(dc, _options) {
return await dc.endDialog(120);
}
}
@ -45,9 +45,7 @@ describe('Dialog', function () {
const dialog = new TestDialog('testDialog');
dialogs.add(dialog);
await adapter.send(beginMessage)
.assertReply('begin called')
.startTest();
await adapter.send(beginMessage).assertReply('begin called').startTest();
});
it('should receive dialog options when beginning a dialog from a dialog set.', async function () {
@ -64,9 +62,7 @@ describe('Dialog', function () {
const dialog = new TestDialog('testDialog');
dialogs.add(dialog);
await adapter.send(beginMessage)
.assertReply('begin called')
.startTest();
await adapter.send(beginMessage).assertReply('begin called').startTest();
});
it('should continue() a multi-turn dialog.', async function () {
@ -75,14 +71,15 @@ describe('Dialog', function () {
const results = await dc.continueDialog();
switch (results.status) {
case DialogTurnStatus.empty:
case DialogTurnStatus.empty: {
await dc.beginDialog('testDialog');
break;
case DialogTurnStatus.complete:
}
case DialogTurnStatus.complete: {
const finalResult = results.result;
await turnContext.sendActivity(finalResult.toString());
break;
}
}
await convoState.saveChanges(turnContext);
});
@ -94,10 +91,6 @@ describe('Dialog', function () {
const dialog = new TestDialog('testDialog');
dialogs.add(dialog);
await adapter.send(beginMessage)
.assertReply('begin called')
.send('continue')
.assertReply('120')
.startTest();
await adapter.send(beginMessage).assertReply('begin called').send('continue').assertReply('120').startTest();
});
});

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

@ -2,8 +2,8 @@ const { ConversationState, MemoryStorage, TestAdapter } = require('botbuilder-co
const { Dialog, DialogContextError, DialogSet, WaterfallDialog, DialogTurnStatus } = require('../');
const assert = require('assert');
const beginMessage = { text: `begin`, type: 'message' };
const continueMessage = { text: `continue`, type: 'message' };
const beginMessage = { text: 'begin', type: 'message' };
const continueMessage = { text: 'continue', type: 'message' };
describe('DialogContext', function () {
this.timeout(5000);
@ -15,7 +15,7 @@ describe('DialogContext', function () {
const results = await dc.beginDialog('a');
if (results.status === DialogTurnStatus.complete) {
assert(results.result === true, `End result from WaterfallDialog was not expected value.`);
assert(results.result === true, 'End result from WaterfallDialog was not expected value.');
}
await convoState.saveChanges(turnContext);
});
@ -29,7 +29,7 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.endDialog(true);
},
])
@ -44,7 +44,7 @@ describe('DialogContext', function () {
const results = await dc.beginDialog('a', { z: 'z' });
if (results.status === DialogTurnStatus.complete) {
assert(results.result === true, `End result from WaterfallDialog was not expected value.`);
assert(results.result === true, 'End result from WaterfallDialog was not expected value.');
}
await convoState.saveChanges(turnContext);
});
@ -56,8 +56,8 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step.options.z === 'z', `Correct DialogOptions was not passed in to WaterfallDialog.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
assert(step.options.z === 'z', 'Correct DialogOptions was not passed in to WaterfallDialog.');
return await step.endDialog(true);
},
])
@ -78,7 +78,7 @@ describe('DialogContext', function () {
(err) => {
assert.strictEqual(
err.message,
`DialogContext.beginDialog(): A dialog with an id of 'b' wasn't found.`,
"DialogContext.beginDialog(): A dialog with an id of 'b' wasn't found.",
`unexpected error message thrown: "${err.message}"`
);
@ -119,11 +119,11 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
assert.strictEqual(
step.options.prompt,
'test',
`promptOrOptions arg was not correctly passed through.`
'promptOrOptions arg was not correctly passed through.'
);
return await step.endDialog();
},
@ -148,7 +148,7 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.endDialog();
},
])
@ -172,9 +172,9 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(Array.isArray(step.options.choices), `choices received in step is not an array.`);
assert.strictEqual(step.options.choices.length, 3, `not all choices were passed in.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
assert(Array.isArray(step.options.choices), 'choices received in step is not an array.');
assert.strictEqual(step.options.choices.length, 3, 'not all choices were passed in.');
return await step.endDialog();
},
])
@ -189,7 +189,7 @@ describe('DialogContext', function () {
const results = await dc.beginDialog('a');
await convoState.saveChanges(turnContext);
assert.strictEqual(results.result, 119, `unexpected results.result value received from 'a' dialog.`);
assert.strictEqual(results.result, 119, "unexpected results.result value received from 'a' dialog.");
});
const convoState = new ConversationState(new MemoryStorage());
@ -199,12 +199,12 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.beginDialog('b');
},
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert.strictEqual(step.result, 120, `incorrect step.result value received from 'b' dialog.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
assert.strictEqual(step.result, 120, "incorrect step.result value received from 'b' dialog.");
return await step.endDialog(119);
},
])
@ -213,7 +213,7 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('b', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.endDialog(120);
},
])
@ -233,7 +233,7 @@ describe('DialogContext', function () {
break;
case DialogTurnStatus.complete:
assert.strictEqual(results.result, true, `received unexpected final result from dialog.`);
assert.strictEqual(results.result, true, 'received unexpected final result from dialog.');
break;
}
await convoState.saveChanges(turnContext);
@ -246,12 +246,12 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
await step.context.sendActivity(`foo`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
await step.context.sendActivity('foo');
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.endDialog(true);
},
])
@ -278,13 +278,13 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert.strictEqual(step.activeDialog.id, 'a', `incorrect value for step.activeDialog.id`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
assert.strictEqual(step.activeDialog.id, 'a', 'incorrect value for step.activeDialog.id');
step.activeDialog.id = 'b';
return Dialog.EndOfTurn;
},
async function (step) {
assert(false, `shouldn't continue`);
async function () {
assert(false, "shouldn't continue");
},
])
);
@ -292,10 +292,10 @@ describe('DialogContext', function () {
await assert.rejects(
async () => await adapter.send(beginMessage).send(continueMessage).startTest(),
(err) => {
assert(err, `Error not found.`);
assert(err, 'Error not found.');
assert.strictEqual(
err.message,
`DialogContext.continueDialog(): Can't continue dialog. A dialog with an id of 'b' wasn't found.`,
"DialogContext.continueDialog(): Can't continue dialog. A dialog with an id of 'b' wasn't found.",
`unexpected error message thrown: "${err.message}"`
);
@ -306,12 +306,12 @@ describe('DialogContext', function () {
);
});
it(`should return a DialogTurnResult if continue() is called without an activeDialog.`, async function () {
it('should return a DialogTurnResult if continue() is called without an activeDialog.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.continueDialog();
assert.strictEqual(typeof results, 'object', `results is not the expected object`);
assert.strictEqual(results.status, DialogTurnStatus.empty, `results.status is not 'empty'.`);
assert.strictEqual(typeof results, 'object', 'results is not the expected object');
assert.strictEqual(results.status, DialogTurnStatus.empty, "results.status is not 'empty'.");
await convoState.saveChanges(turnContext);
});
@ -328,7 +328,7 @@ describe('DialogContext', function () {
const dc = await dialogs.createContext(turnContext);
const results = await dc.beginDialog('a');
assert.strictEqual(results.result, true, `received unexpected final result from dialog.`);
assert.strictEqual(results.result, true, 'received unexpected final result from dialog.');
await convoState.saveChanges(turnContext);
});
@ -340,13 +340,13 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.beginDialog('b');
},
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step.context.activity.text, 'begin', `unexpected message received.`);
assert(step.result, `ended dialog.`, `unexpected step.result received.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
assert(step.context.activity.text, 'begin', 'unexpected message received.');
assert(step.result, 'ended dialog.', 'unexpected step.result received.');
return await step.endDialog(true);
},
])
@ -355,7 +355,7 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('b', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.endDialog('ended dialog.');
},
])
@ -364,17 +364,17 @@ describe('DialogContext', function () {
await adapter.send(beginMessage).startTest();
});
it(`should accept calls to end when no activeDialogs or parent dialogs exist.`, async function () {
it('should accept calls to end when no activeDialogs or parent dialogs exist.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.endDialog();
await convoState.saveChanges(turnContext);
assert.strictEqual(results.status, DialogTurnStatus.complete, `results.status not equal 'complete'.`);
assert.strictEqual(results.status, DialogTurnStatus.complete, "results.status not equal 'complete'.");
assert.strictEqual(
results.result,
undefined,
`received unexpected value for results.result (expected undefined).`
'received unexpected value for results.result (expected undefined).'
);
});
@ -386,7 +386,7 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.replaceDialog('b', { z: step.options.z });
},
])
@ -395,13 +395,13 @@ describe('DialogContext', function () {
await adapter.send(beginMessage).startTest();
});
it(`should replace() dialog.`, async function () {
it('should replace() dialog.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.beginDialog('a', { z: 'z' });
await convoState.saveChanges(turnContext);
assert.strictEqual(results.result, 'z', `received unexpected final result from dialog.`);
assert.strictEqual(results.result, 'z', 'received unexpected final result from dialog.');
});
const convoState = new ConversationState(new MemoryStorage());
@ -412,7 +412,7 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.replaceDialog('b', { z: step.options.z });
},
])
@ -421,9 +421,9 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('b', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert.strictEqual(step.stack.length, 1, `current DialogContext.stack.length should be 1.`);
assert.strictEqual(step.options.z, 'z', `incorrect step.options received.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
assert.strictEqual(step.stack.length, 1, 'current DialogContext.stack.length should be 1.');
assert.strictEqual(step.options.z, 'z', 'incorrect step.options received.');
return await step.endDialog(step.options.z);
},
])
@ -432,7 +432,7 @@ describe('DialogContext', function () {
await adapter.send(beginMessage).startTest();
});
it(`should begin dialog if stack empty when replaceDialog() called with valid dialogId.`, async function () {
it('should begin dialog if stack empty when replaceDialog() called with valid dialogId.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
@ -447,7 +447,7 @@ describe('DialogContext', function () {
dialogs.add(
new WaterfallDialog('b', [
async function (step) {
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
return await step.endDialog();
},
])

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

@ -179,7 +179,7 @@ class ComponentDialogWithCancellation extends ComponentDialog {
describe('runDialog()', function () {
this.timeout(300);
describe('parameter validation', () => {
describe('parameter validation', function () {
it('should throw if missing dialog parameter', async function () {
await assert.rejects(async () => runDialog(), {
message: 'runDialog(): missing dialog',
@ -205,7 +205,7 @@ describe('runDialog()', function () {
});
});
describe('HandlesBotAndSkillsTestCases', () => {
describe('HandlesBotAndSkillsTestCases', function () {
this.beforeEach(() => {
_eocSent = undefined;
});
@ -231,25 +231,25 @@ describe('runDialog()', function () {
}
}
it('rootBotOnly, no sent EoC', async () => {
it('rootBotOnly, no sent EoC', async function () {
await handlesBotAndSkillsTestCases(FlowTestCase.RootBotOnly, false);
});
it('rootBotConsumingSkill, no sent EoC', async () => {
it('rootBotConsumingSkill, no sent EoC', async function () {
await handlesBotAndSkillsTestCases(FlowTestCase.RootBotConsumingSkill, false);
});
it('middleSkill, sent EoC', async () => {
it('middleSkill, sent EoC', async function () {
await handlesBotAndSkillsTestCases(FlowTestCase.MiddleSkill, true);
});
it('leafSkill, sent EoC', async () => {
it('leafSkill, sent EoC', async function () {
await handlesBotAndSkillsTestCases(FlowTestCase.LeafSkill, true);
});
});
describe('HandlesEarlyDialogEndings', () => {
it('handles premature dialog ending', async () => {
describe('HandlesEarlyDialogEndings', function () {
it('handles premature dialog ending', async function () {
const dialog = new ComponentDialogWithPrematureEnd();
const testFlow = createTestFlow(dialog, FlowTestCase.MiddleSkill);
await testFlow.send('Hi').startTest();
@ -259,7 +259,7 @@ describe('runDialog()', function () {
assert.strictEqual(_eocSent.type, ActivityTypes.EndOfConversation);
assert.strictEqual(_eocSent.code, EndOfConversationCodes.CompletedSuccessfully);
});
it('handles premature dialog cancellation', async () => {
it('handles premature dialog cancellation', async function () {
const dialog = new ComponentDialogWithCancellation();
const testFlow = createTestFlow(dialog, FlowTestCase.MiddleSkill);
await testFlow.send('Hi').startTest();

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

@ -2,8 +2,8 @@ const { ConversationState, MemoryStorage, TestAdapter, NullTelemetryClient } = r
const { Dialog, DialogSet, WaterfallDialog, DialogTurnStatus, ComponentDialog } = require('../');
const assert = require('assert');
const beginMessage = { text: `begin`, type: 'message' };
const continueMessage = { text: `continue`, type: 'message' };
const beginMessage = { text: 'begin', type: 'message' };
const continueMessage = { text: 'continue', type: 'message' };
describe('DialogSet', function () {
this.timeout(5000);
@ -54,8 +54,8 @@ describe('DialogSet', function () {
},
])
);
assert(dialogs.find('A'), `dialog A not found.`);
assert(dialogs.find('B'), `dialog B not found.`);
assert(dialogs.find('A'), 'dialog A not found.');
assert(dialogs.find('B'), 'dialog B not found.');
});
it('should increment the dialog ID when adding the same dialog twice.', function () {
@ -65,15 +65,15 @@ describe('DialogSet', function () {
dialogs.add(new WaterfallDialog('a', [function () {}]));
assert(dialogs.find('a'));
assert(dialogs.find('a2'), `second dialog didn't have ID incremented`);
assert(dialogs.find('a2'), "second dialog didn't have ID incremented");
});
it('should find() a dialog that was added.', function () {
const dialogs = new DialogSet(dialogState);
dialogs.add(new WaterfallDialog('a', [function () {}]));
assert(dialogs.find('a'), `dialog not found.`);
assert(!dialogs.find('b'), `dialog found that shouldn't exist.`);
assert(dialogs.find('a'), 'dialog not found.');
assert(!dialogs.find('b'), "dialog found that shouldn't exist.");
});
it('should save dialog stack state between turns.', async function () {
@ -85,7 +85,7 @@ describe('DialogSet', function () {
new WaterfallDialog('a', [
async function (step) {
assert(step);
await step.context.sendActivity(`Greetings`);
await step.context.sendActivity('Greetings');
return Dialog.EndOfTurn;
},
async function (step) {
@ -117,17 +117,17 @@ describe('DialogSet', function () {
const dialogs = new DialogSet(dialogState);
dialogs.add(new WaterfallDialog('A')).add(new WaterfallDialog('B'));
const hash = dialogs.getVersion();
assert(hash && hash.length > 0, `no hash generated.`);
assert(hash && hash.length > 0, 'no hash generated.');
});
it('Generated version hash should change when dialog set changes.', function () {
const dialogs = new DialogSet(dialogState);
dialogs.add(new WaterfallDialog('A')).add(new WaterfallDialog('B'));
const hash = dialogs.getVersion();
assert(hash && hash.length > 0, `no hash generated.`);
assert(hash && hash.length > 0, 'no hash generated.');
dialogs.add(new WaterfallDialog('C'));
assert(hash != dialogs.getVersion(), `hash not updated.`);
assert(hash != dialogs.getVersion(), 'hash not updated.');
});
it('Cyclical dialog structures', function () {

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

@ -11,7 +11,7 @@ const {
} = require('../..');
const beginMessage = {
text: `begin`,
text: 'begin',
type: 'message',
channelId: 'test',
from: { id: 'user' },
@ -122,9 +122,9 @@ describe('Dialog State Manager', function () {
it('create a standard configuration by default.', function () {
const config = this.dc.state.configuration;
assert(config, `No config returned`);
assert(config.pathResolvers.length > 0, `No path resolvers`);
assert(config.memoryScopes.length > 0, `No memory scopes`);
assert(config, 'No config returned');
assert(config.pathResolvers.length > 0, 'No path resolvers');
assert(config.memoryScopes.length > 0, 'No memory scopes');
});
it('read values from the SETTINGS memory scope.', function () {
@ -315,7 +315,7 @@ describe('Dialog State Manager', function () {
},
});
const value = this.dc.state.getValue(`turn.addresses['work'].zip`);
const value = this.dc.state.getValue("turn.addresses['work'].zip");
assert(value == '98052');
});
@ -329,7 +329,7 @@ describe('Dialog State Manager', function () {
},
});
const value = this.dc.state.getValue(`turn.addresses["work"].zip`);
const value = this.dc.state.getValue('turn.addresses["work"].zip');
assert(value == '98052');
});
@ -343,7 +343,7 @@ describe('Dialog State Manager', function () {
},
});
const value = this.dc.state.getValue(`turn.addresses['\\"work\\"'].zip`);
const value = this.dc.state.getValue('turn.addresses[\'\\"work\\"\'].zip');
assert(value == '98052');
});
@ -358,7 +358,7 @@ describe('Dialog State Manager', function () {
},
});
this.dc.state.getValue(`turn.addresses['work"].zip`);
this.dc.state.getValue('turn.addresses[\'work"].zip');
});
});
@ -373,23 +373,23 @@ describe('Dialog State Manager', function () {
},
});
this.dc.state.getValue(`turn.addresses.~work.zip`);
this.dc.state.getValue('turn.addresses.~work.zip');
});
});
it('raise an error for assignments to a negative array index.', function () {
assert.throws(() => this.dc.state.setValue(`turn.foo[-1]`, 'test'));
assert.throws(() => this.dc.state.setValue('turn.foo[-1]', 'test'));
});
it('raise an error for array assignments to non-array values.', function () {
assert.throws(() => {
this.dc.state.setValue('turn.foo', 'bar');
this.dc.state.setValue(`turn.foo[3]`, 'test');
this.dc.state.setValue('turn.foo[3]', 'test');
});
});
it('raise an error for un-matched brackets.', function () {
assert.throws(() => this.dc.state.setValue(`turn.foo[0`, 'test'));
assert.throws(() => this.dc.state.setValue('turn.foo[0', 'test'));
});
it('alow indexer based path lookups.', function () {

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

@ -1,4 +1,4 @@
const _ = require('lodash');
const pick = require('lodash/pick');
const assert = require('assert');
const { ConversationState, UserState, MemoryStorage, TurnContext, TestAdapter } = require('botbuilder-core');
@ -19,7 +19,7 @@ const {
} = require('../..');
const beginMessage = {
text: `begin`,
text: 'begin',
type: 'message',
channelId: 'test',
from: { id: 'user' },
@ -106,7 +106,7 @@ describe('Memory Scopes', function () {
it('finds registered dialog', async function () {
const { memory } = await initialize();
assert.deepStrictEqual(_.pick(memory, 'message', 'expression'), {
assert.deepStrictEqual(pick(memory, 'message', 'expression'), {
message: 'test message',
expression: 'resolved value',
});
@ -151,7 +151,7 @@ describe('Memory Scopes', function () {
const dc = await dialogs.createContext(context);
const scope = new ConversationMemoryScope();
const memory = scope.getMemory(dc);
assert.deepStrictEqual(_.pick(memory, 'conversation'), { conversation: { foo: 'bar' } });
assert.deepStrictEqual(pick(memory, 'conversation'), { conversation: { foo: 'bar' } });
});
});
@ -195,7 +195,7 @@ describe('Memory Scopes', function () {
await scope.load(dc);
memory = scope.getMemory(dc);
assert.deepStrictEqual(_.pick(memory, 'user'), { user: { foo: 'bar' } });
assert.deepStrictEqual(pick(memory, 'user'), { user: { foo: 'bar' } });
});
});
@ -218,7 +218,7 @@ describe('Memory Scopes', function () {
it('returns containers state', async function () {
const { memory } = await initialize();
assert.deepStrictEqual(_.pick(memory, 'isContainer'), { isContainer: true });
assert.deepStrictEqual(pick(memory, 'isContainer'), { isContainer: true });
});
it('returns parent containers state for children', async function () {
@ -228,12 +228,12 @@ describe('Memory Scopes', function () {
assert(dc.child);
const memory = scope.getMemory(dc.child);
assert.deepStrictEqual(_.pick(memory, 'isContainer'), { isContainer: true });
assert.deepStrictEqual(pick(memory, 'isContainer'), { isContainer: true });
});
it('returns childs state when no parent', async function () {
const { memory } = await initialize(new TestDialog('test', 'test message'));
assert.deepStrictEqual(_.pick(memory, 'isDialog'), { isDialog: true });
assert.deepStrictEqual(pick(memory, 'isDialog'), { isDialog: true });
});
it('overwrites parents memory', async function () {
@ -245,7 +245,7 @@ describe('Memory Scopes', function () {
scope.setMemory(dc.child, { foo: 'bar' });
const memory = scope.getMemory(dc);
assert.deepStrictEqual(_.pick(memory, 'foo'), { foo: 'bar' });
assert.deepStrictEqual(pick(memory, 'foo'), { foo: 'bar' });
});
it('overwrites active dialogs memory', async function () {
@ -254,7 +254,7 @@ describe('Memory Scopes', function () {
scope.setMemory(dc, { foo: 'bar' });
const memory = scope.getMemory(dc);
assert.deepStrictEqual(_.pick(memory, 'foo'), { foo: 'bar' });
assert.deepStrictEqual(pick(memory, 'foo'), { foo: 'bar' });
});
it('raises error if setMemory() called without memory', async function () {
@ -291,7 +291,7 @@ describe('Memory Scopes', function () {
dc.context.turnState.set('settings', require('../test.settings.json'));
});
assert.deepStrictEqual(_.pick(memory, 'string', 'int', 'array'), {
assert.deepStrictEqual(pick(memory, 'string', 'int', 'array'), {
string: 'test',
int: 3,
array: ['zero', 'one', 'two', 'three'],
@ -320,7 +320,7 @@ describe('Memory Scopes', function () {
});
assert.deepStrictEqual(
_.pick(memory, 'array', 'object', 'simple', 'MicrosoftAppPassword', 'runtimeSettings', 'BlobsStorage'),
pick(memory, 'array', 'object', 'simple', 'MicrosoftAppPassword', 'runtimeSettings', 'BlobsStorage'),
{
array: ['one', 'two'],
object: {
@ -357,7 +357,7 @@ describe('Memory Scopes', function () {
});
assert.deepStrictEqual(
_.pick(
pick(
memory,
'array',
'object',
@ -456,13 +456,13 @@ describe('Memory Scopes', function () {
it('returns active dialogs state', async function () {
const { memory } = await initialize({ dialog: new TestDialog('test', 'test message') });
assert(_.pick(memory, 'isDialog'), { isDialog: true });
assert(pick(memory, 'isDialog'), { isDialog: true });
});
it('overwrites active dialogs memory', async function () {
const { dc, memory, scope } = await initialize();
scope.setMemory(dc, { foo: 'bar' });
assert(_.pick(memory, 'foo'), { foo: 'bar' });
assert(pick(memory, 'foo'), { foo: 'bar' });
});
it('raises error if setMemory() called without memory', async function () {
@ -520,7 +520,7 @@ describe('Memory Scopes', function () {
scope.setMemory(dc, { foo: 'bar' });
const memory = scope.getMemory(dc);
assert.deepStrictEqual(_.pick(memory, 'foo'), { foo: 'bar' });
assert.deepStrictEqual(pick(memory, 'foo'), { foo: 'bar' });
});
it('raises error when setMemory() called without memory', async function () {

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

@ -46,7 +46,7 @@ describe('NumberPrompt', function () {
(turnContext, result) => turnContext.sendActivity(result.toString()),
(prompt) => {
assert(prompt);
let value = prompt.recognized.value;
const value = prompt.recognized.value;
return value !== undefined && value >= 1 && value <= 100;
}
);
@ -71,7 +71,7 @@ describe('NumberPrompt', function () {
(turnContext, result) => turnContext.sendActivity(result.toString()),
(prompt) => {
assert(prompt);
let value = prompt.recognized.value;
const value = prompt.recognized.value;
return value !== undefined && value >= 1 && value <= 100;
}
);
@ -96,7 +96,7 @@ describe('NumberPrompt', function () {
(turnContext, result) => turnContext.sendActivity(result.toString()),
async (prompt) => {
assert(prompt);
let value = prompt.recognized.value;
const value = prompt.recognized.value;
const valid = value !== undefined && value >= 1 && value <= 100;
if (!valid) {
await prompt.context.sendActivity('out of range');
@ -121,7 +121,7 @@ describe('NumberPrompt', function () {
(turnContext, result) => turnContext.sendActivity(result.toString()),
(prompt) => {
assert(prompt);
let value = prompt.recognized.value;
const value = prompt.recognized.value;
return value !== undefined && value >= 1 && value <= 100;
}
);

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

@ -3,7 +3,7 @@
const assert = require('assert');
const { spy } = require('sinon');
const { ok, strictEqual } = require('assert');
const { ok } = require('assert');
const { OAuthPrompt, DialogSet, DialogTurnStatus } = require('../');
const {
AuthenticationConstants,
@ -42,9 +42,9 @@ describe('OAuthPrompt', function () {
await dc.prompt('prompt', {});
} else if (results.status === DialogTurnStatus.complete) {
if (results.result.token) {
await turnContext.sendActivity(`Logged in.`);
await turnContext.sendActivity('Logged in.');
} else {
await turnContext.sendActivity(`Failed`);
await turnContext.sendActivity('Failed');
}
}
await convoState.saveChanges(turnContext);
@ -106,9 +106,9 @@ describe('OAuthPrompt', function () {
await dc.prompt('prompt', {});
} else if (results.status === DialogTurnStatus.complete) {
if (results.result.token) {
await turnContext.sendActivity(`Logged in.`);
await turnContext.sendActivity('Logged in.');
} else {
await turnContext.sendActivity(`Failed`);
await turnContext.sendActivity('Failed');
}
}
await convoState.saveChanges(turnContext);
@ -350,9 +350,9 @@ describe('OAuthPrompt', function () {
await dc.prompt('prompt', {});
} else if (results.status === DialogTurnStatus.complete) {
if (results.result.token) {
await turnContext.sendActivity(`Logged in.`);
await turnContext.sendActivity('Logged in.');
} else {
await turnContext.sendActivity(`Failed`);
await turnContext.sendActivity('Failed');
}
}
await convoState.saveChanges(turnContext);
@ -455,7 +455,7 @@ describe('OAuthPrompt', function () {
async exchangeToken() {}
}
it(`should fail if adapter does not have 'getUserToken'`, async function () {
it("should fail if adapter does not have 'getUserToken'", async function () {
const fakeAdapter = {};
const context = new TurnContext(fakeAdapter, {
activity: {
@ -869,7 +869,7 @@ describe('OAuthPrompt', function () {
await dc.prompt('OAuthPrompt', {});
} else if (results.status === DialogTurnStatus.complete) {
if (results.result.token) {
await turnContext.sendActivity(`Logged in.`);
await turnContext.sendActivity('Logged in.');
} else {
await turnContext.sendActivity('Failed');
}
@ -1089,8 +1089,8 @@ class ClaimsIdentity {
/**w
* Each claim should be { type: 'type', value: 'value' }
*
* @param {*} claims
* @param {*} isAuthenticated
* @param {*} claims The claims with which to populate the claims identity.
* @param {*} isAuthenticated True if the identity has been authenticated; otherwise, false.
*/
constructor(claims = [], isAuthenticated = false) {
this.claims = claims;

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

@ -1,24 +1,14 @@
const assert = require('assert');
const { PromptCultureModels } = require('../lib')
const { PromptCultureModels } = require('../lib');
describe('Prompt Culture Models Tests', function() {
describe('Prompt Culture Models Tests', function () {
this.timeout(5000);
it('should correctly map to nearest language', function() {
const locales = [
'es-es',
'nl-nl',
'en-us',
'fr-fr',
'de-de',
'ja-jp',
'it-it',
'pt-br',
'zh-cn'
];
it('should correctly map to nearest language', function () {
const locales = ['es-es', 'nl-nl', 'en-us', 'fr-fr', 'de-de', 'ja-jp', 'it-it', 'pt-br', 'zh-cn'];
// es-ES
const capEnding = (locale) => {
return `${ locale.split('-')[0] }-${ locale.split('-')[1].toUpperCase() }`;
return `${locale.split('-')[0]}-${locale.split('-')[1].toUpperCase()}`;
};
// es-Es
const titleEnding = (locale) => {
@ -41,7 +31,7 @@ describe('Prompt Culture Models Tests', function() {
capEnding(locale),
titleEnding(locale),
capTwoLetter(locale),
lowerTwoLetter(locale)
lowerTwoLetter(locale),
];
return obj;
}, {});
@ -52,13 +42,13 @@ describe('Prompt Culture Models Tests', function() {
});
});
});
it('should not throw when locale is null or undefined', function() {
it('should not throw when locale is null or undefined', function () {
assert.doesNotThrow(() => PromptCultureModels.mapToNearestLanguage(null));
assert.doesNotThrow(() => PromptCultureModels.mapToNearestLanguage(undefined));
});
it('should return all supported cultures', function() {
it('should return all supported cultures', function () {
const expected = [
PromptCultureModels.Chinese,
PromptCultureModels.Dutch,
@ -68,11 +58,11 @@ describe('Prompt Culture Models Tests', function() {
PromptCultureModels.Italian,
PromptCultureModels.Japanese,
PromptCultureModels.Portuguese,
PromptCultureModels.Spanish
PromptCultureModels.Spanish,
];
const supportedCultures = PromptCultureModels.getSupportedCultures();
assert.deepEqual(supportedCultures, expected);
});
});
});

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

@ -41,7 +41,7 @@ describe('SkillDialog', function () {
* @remarks
* Port of BeginDialogShouldCallSkill from C#
* https://github.com/microsoft/botbuilder-dotnet/blob/41120728b22c709ec2d9247393505fdc778b2de1/tests/Microsoft.Bot.Builder.Dialogs.Tests/SkillDialogTests.cs#L47-L49
* @param {string} deliveryMode
* @param {string} deliveryMode The delivery mode to test.
*/
async function beginDialogShouldCallSkill(deliveryMode, useCreateSkillConversationId = false) {
let activitySent; // Activity
@ -313,7 +313,7 @@ describe('SkillDialog', function () {
});
describe('(private) sendToSkill()', function () {
it(`should rethrow the error if its message is not "Not Implemented" error`, async function () {
it('should rethrow the error if its message is not "Not Implemented" error', async function () {
const adapter = new TestAdapter(/* logic param not required */);
const activity = { type: ActivityTypes.Message, channelId: Channels.Directline, conversation: { id: '1' } };
const context = new TurnContext(adapter, activity);
@ -576,7 +576,7 @@ describe('SkillDialog', function () {
* @remarks
* captureAction should match the below signature:
* `(fromBotId: string, toBotId: string, toUrl: string, serviceUrl: string, conversationId: string, activity: Activity) => void`
* @param {Function} captureAction
* @param {Function} captureAction Callback to capture the parameters sent to the skill.
* @param {StatusCodes} returnStatusCode Defaults to StatusCodes.OK
* @returns [BotFrameworkHttpClient, postActivityStub]
*/
@ -615,7 +615,7 @@ function createSkillClientAndStub(captureAction, returnStatusCode = StatusCodes.
/**
*
* @param {string} uri
* @param {string} uri Uri for the token exchange.
*/
function createOAuthCardAttachmentActivity(uri) {
const oauthCard = {
@ -635,8 +635,8 @@ function createOAuthCardAttachmentActivity(uri) {
}
/**
* @param {*} conversationState
* @param {*} mockSkillClient
* @param {*} conversationState The conversation state object.
* @param {*} mockSkillClient The skill client mock.
* @returns A Skill Dialog Options object.
*/
function createSkillDialogOptions(conversationState, mockSkillClient, connectionName, useCreateSkillConversationId) {

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

@ -6,10 +6,10 @@ const path = require('path');
const invalidMessage = { type: ActivityTypes.Message, text: '' };
describe('TextPrompt', function() {
describe('TextPrompt', function () {
this.timeout(5000);
it('should call TextPrompt using dc.prompt().', async function() {
it('should call TextPrompt using dc.prompt().', async function () {
// Initialize TestAdapter.
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
@ -31,14 +31,10 @@ describe('TextPrompt', function() {
const dialogs = new DialogSet(dialogState);
dialogs.add(new TextPrompt('prompt'));
await adapter.send('Hello')
.assertReply('Please say something.')
.send('test')
.assertReply('test')
.startTest();
await adapter.send('Hello').assertReply('Please say something.').send('test').assertReply('test').startTest();
});
it('should call TextPrompt with custom validator.', async function() {
it('should call TextPrompt with custom validator.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
@ -56,12 +52,15 @@ describe('TextPrompt', function() {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new TextPrompt('prompt', async (prompt) => {
assert(prompt);
return prompt.recognized.value.length >= 3;
}));
dialogs.add(
new TextPrompt('prompt', async (prompt) => {
assert(prompt);
return prompt.recognized.value.length >= 3;
})
);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please say something.')
.send('i')
.assertReply('Please say something.')
@ -70,7 +69,7 @@ describe('TextPrompt', function() {
.startTest();
});
it('should call TextPrompt with naughty strings.', async function() {
it('should call TextPrompt with naughty strings.', async function () {
const filePath = path.join(__dirname, 'Resources', 'naughtyStrings.txt');
lineReader.eachLine(filePath, async (naughtyString) => {
@ -83,8 +82,8 @@ describe('TextPrompt', function() {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
const results = await dc.continueDialog();
if (results.status === DialogTurnStatus.empty){
await dc.prompt('prompt', { prompt: 'Enter some text'});
if (results.status === DialogTurnStatus.empty) {
await dc.prompt('prompt', { prompt: 'Enter some text' });
} else if (results.status === DialogTurnStatus.complete) {
const reply = results.result;
await turnContext.sendActivity(reply);
@ -92,7 +91,8 @@ describe('TextPrompt', function() {
await convoState.saveChanges(turnContext);
});
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Enter some text')
.send(naughtyString)
.assertReply(naughtyString)
@ -101,7 +101,7 @@ describe('TextPrompt', function() {
});
});
it('should send custom retryPrompt.', async function() {
it('should send custom retryPrompt.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
@ -121,7 +121,8 @@ describe('TextPrompt', function() {
const dialogs = new DialogSet(dialogState);
dialogs.add(new TextPrompt('prompt'));
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please say something.')
.send(invalidMessage)
.assertReply('Text is required.')
@ -130,7 +131,7 @@ describe('TextPrompt', function() {
.startTest();
});
it('should send ignore retryPrompt if validator replies.', async function() {
it('should send ignore retryPrompt if validator replies.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
@ -148,16 +149,19 @@ describe('TextPrompt', function() {
const dialogState = convoState.createProperty('dialogState');
const dialogs = new DialogSet(dialogState);
dialogs.add(new TextPrompt('prompt', async (prompt) => {
assert(prompt);
const valid = prompt.recognized.value.length >= 3;
if (!valid) {
await prompt.context.sendActivity('too short');
}
return valid;
}));
dialogs.add(
new TextPrompt('prompt', async (prompt) => {
assert(prompt);
const valid = prompt.recognized.value.length >= 3;
if (!valid) {
await prompt.context.sendActivity('too short');
}
return valid;
})
);
await adapter.send('Hello')
await adapter
.send('Hello')
.assertReply('Please say something.')
.send('i')
.assertReply('too short')
@ -166,7 +170,7 @@ describe('TextPrompt', function() {
.startTest();
});
it('should not send any retryPrompt no prompt specified.', async function() {
it('should not send any retryPrompt no prompt specified.', async function () {
const adapter = new TestAdapter(async (turnContext) => {
const dc = await dialogs.createContext(turnContext);
@ -186,10 +190,6 @@ describe('TextPrompt', function() {
const dialogs = new DialogSet(dialogState);
dialogs.add(new TextPrompt('prompt'));
await adapter.send('Hello')
.send(invalidMessage)
.send('test')
.assertReply('test')
.startTest();
await adapter.send('Hello').send(invalidMessage).send('test').assertReply('test').startTest();
});
});

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

@ -3,7 +3,7 @@ const { Dialog, DialogReason, DialogSet, DialogTurnStatus, WaterfallDialog, Comp
const assert = require('assert');
const beginMessage = { text: `begin`, type: 'message' };
const beginMessage = { text: 'begin', type: 'message' };
class MyWaterfall extends WaterfallDialog {
constructor(dialogId) {
@ -171,7 +171,7 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step.options && step.options.test === 'test', `step.options not found.`);
assert(step.options && step.options.test === 'test', 'step.options not found.');
await step.context.sendActivity('bot responding.');
return await step.next(step.options.test);
},
@ -212,8 +212,8 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `step not found.`);
assert(step.options, `step.options not found.`);
assert(step, 'step not found.');
assert(step.options, 'step.options not found.');
assert.strictEqual(
step.options.test,
'test',
@ -260,8 +260,8 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `step not found.`);
assert(step.options, `step.options not found.`);
assert(step, 'step not found.');
assert(step.options, 'step.options not found.');
assert.strictEqual(
step.options.test,
'test1',
@ -272,8 +272,8 @@ describe('WaterfallDialog', function () {
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `step not found.`);
assert(step.options, `step.options not found.`);
assert(step, 'step not found.');
assert(step.options, 'step.options not found.');
assert.strictEqual(
step.options.test,
'test2',
@ -284,7 +284,7 @@ describe('WaterfallDialog', function () {
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
assert.strictEqual(
step.options.test,
'test3',
@ -328,15 +328,15 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `step not found.`);
assert.equal(typeof step.values, 'object', `initial step.values should be an object.`);
assert(step, 'step not found.');
assert.equal(typeof step.values, 'object', 'initial step.values should be an object.');
step.values.test = 'test1';
await step.context.sendActivity('bot responding.');
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `step not found.`);
assert(step.values, `step.values not found.`);
assert(step, 'step not found.');
assert(step.values, 'step.values not found.');
assert.strictEqual(
step.values.test,
'test1',
@ -347,8 +347,8 @@ describe('WaterfallDialog', function () {
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `step not found.`);
assert(step.values, `step.values not found.`);
assert(step, 'step not found.');
assert(step.values, 'step.values not found.');
assert.strictEqual(
step.values.test,
'test1',
@ -397,15 +397,15 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `step not found.`);
assert.equal(typeof step.values, 'object', `initial step.values should be an object.`);
assert(step, 'step not found.');
assert.equal(typeof step.values, 'object', 'initial step.values should be an object.');
step.values.test = 'test1';
await step.context.sendActivity('bot responding.');
return await step.beginDialog('b');
},
async function (step) {
assert(step, `step not found.`);
assert(step.values, `step.values not found.`);
assert(step, 'step not found.');
assert(step.values, 'step.values not found.');
assert.strictEqual(
step.values.test,
'test1',
@ -414,7 +414,7 @@ describe('WaterfallDialog', function () {
assert.strictEqual(
step.values.test_b,
undefined,
`step.values.test_b should not be available in WaterfallDialog('a').`
"step.values.test_b should not be available in WaterfallDialog('a')."
);
return await step.endDialog('ending WaterfallDialog.');
},
@ -424,15 +424,15 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('b', [
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
assert.equal(
typeof step.values,
'object',
`new step.values for second WaterfallDialog should be an object.`
'new step.values for second WaterfallDialog should be an object.'
);
assert(
!step.values.test,
`new WaterfallDialog's step.values shouldn't have values from parent dialog's step.values.`
"new WaterfallDialog's step.values shouldn't have values from parent dialog's step.values."
);
// Add a new value to this WaterfallDialog's step.values.
@ -441,20 +441,20 @@ describe('WaterfallDialog', function () {
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
assert.equal(
typeof step.values,
'object',
`step.values for second WaterfallDialog should be an object.`
'step.values for second WaterfallDialog should be an object.'
);
assert(
!step.values.test,
`new WaterfallDialog's step.values shouldn't have values from parent dialog's step.values.`
"new WaterfallDialog's step.values shouldn't have values from parent dialog's step.values."
);
assert.strictEqual(
step.values.test_b,
'test_b',
`step.values.test_b should not be available in WaterfallDialog 'a'.`
"step.values.test_b should not be available in WaterfallDialog 'a'."
);
return await step.endDialog();
@ -493,8 +493,8 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `step not found.`);
assert(step.options, `step.options not found.`);
assert(step, 'step not found.');
assert(step.options, 'step.options not found.');
assert.strictEqual(
step.options.test_a,
'test_a',
@ -504,8 +504,8 @@ describe('WaterfallDialog', function () {
return await step.beginDialog('b');
},
async function (step) {
assert(step, `step not found.`);
assert(step.options, `step.options not found.`);
assert(step, 'step not found.');
assert(step.options, 'step.options not found.');
assert.strictEqual(
step.options.test_a,
'test_a',
@ -519,8 +519,8 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('b', [
async function (step) {
assert(step, `step not found.`);
assert(step.options, `step.options not found.`);
assert(step, 'step not found.');
assert(step.options, 'step.options not found.');
assert.strictEqual(
step.options.test_a,
undefined,
@ -530,8 +530,8 @@ describe('WaterfallDialog', function () {
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `step not found.`);
assert(step.options, `step.options not found.`);
assert(step, 'step not found.');
assert(step.options, 'step.options not found.');
assert.strictEqual(
step.options.test_b,
'test_b',
@ -573,12 +573,12 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
await step.context.sendActivity('bot responding.');
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
return Dialog.EndOfTurn;
},
])
@ -616,7 +616,7 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
await step.context.sendActivity('bot responding.');
try {
await step.next();
@ -624,17 +624,17 @@ describe('WaterfallDialog', function () {
} catch (err) {
assert(
err.message ===
`WaterfallStepContext.next(): method already called for dialog and step 'a[0]'.`,
"WaterfallStepContext.next(): method already called for dialog and step 'a[0]'.",
err.message
);
}
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
},
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
},
])
);
@ -664,12 +664,12 @@ describe('WaterfallDialog', function () {
dialogs.add(
new WaterfallDialog('a', [
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
await step.context.sendActivity('bot responding.');
return Dialog.EndOfTurn;
},
async function (step) {
assert(step, `step not found.`);
assert(step, 'step not found.');
assert(
step.context.activity.text === 'continue.',
`expected "continue." not ${step.context.activity.text}`