cohit's picture
Upload folder using huggingface_hub
0827183 verified
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
from typing import Callable
import aiounittest
from recognizers_text import Culture
from botbuilder.dialogs import DialogContext, DialogTurnResult
from botbuilder.dialogs.prompts import (
NumberPrompt,
PromptOptions,
PromptValidatorContext,
)
from botbuilder.core import (
MemoryStorage,
ConversationState,
TurnContext,
MessageFactory,
)
from botbuilder.core.adapters import TestAdapter, TestFlow
from botbuilder.dialogs import DialogSet, DialogTurnStatus
from botbuilder.schema import Activity, ActivityTypes
class NumberPromptMock(NumberPrompt):
def __init__(
self,
dialog_id: str,
validator: Callable[[PromptValidatorContext], bool] = None,
default_locale=None,
):
super().__init__(dialog_id, validator, default_locale)
async def on_prompt_null_context(self, options: PromptOptions):
# Should throw TypeError
await self.on_prompt(
turn_context=None, state=None, options=options, is_retry=False
)
async def on_prompt_null_options(self, dialog_context: DialogContext):
# Should throw TypeError
await self.on_prompt(
dialog_context.context, state=None, options=None, is_retry=False
)
async def on_recognize_null_context(self):
# Should throw TypeError
await self.on_recognize(turn_context=None, state=None, options=None)
class NumberPromptTests(aiounittest.AsyncTestCase):
def test_empty_id_should_fail(self):
# pylint: disable=no-value-for-parameter
empty_id = ""
self.assertRaises(TypeError, lambda: NumberPrompt(empty_id))
def test_none_id_should_fail(self):
# pylint: disable=no-value-for-parameter
self.assertRaises(TypeError, lambda: NumberPrompt(dialog_id=None))
async def test_with_null_turn_context_should_fail(self):
number_prompt_mock = NumberPromptMock("NumberPromptMock")
options = PromptOptions(
prompt=Activity(type=ActivityTypes.message, text="Please send a number.")
)
with self.assertRaises(TypeError):
await number_prompt_mock.on_prompt_null_context(options)
async def test_on_prompt_with_null_options_fails(self):
conver_state = ConversationState(MemoryStorage())
dialog_state = conver_state.create_property("dialogState")
dialogs = DialogSet(dialog_state)
number_prompt_mock = NumberPromptMock(
dialog_id="NumberPromptMock", validator=None, default_locale=Culture.English
)
dialogs.add(number_prompt_mock)
with self.assertRaises(TypeError):
await number_prompt_mock.on_recognize_null_context()
async def test_number_prompt(self):
# Create new ConversationState with MemoryStorage and register the state as middleware.
conver_state = ConversationState(MemoryStorage())
# Create a DialogState property, DialogSet and register the WaterfallDialog.
dialog_state = conver_state.create_property("dialogState")
dialogs = DialogSet(dialog_state)
# Create and add number prompt to DialogSet.
number_prompt = NumberPrompt("NumberPrompt", None, Culture.English)
dialogs.add(number_prompt)
async def exec_test(turn_context: TurnContext) -> None:
dialog_context = await dialogs.create_context(turn_context)
results = await dialog_context.continue_dialog()
if results.status == DialogTurnStatus.Empty:
await dialog_context.begin_dialog(
"NumberPrompt",
PromptOptions(
prompt=MessageFactory.text("Enter quantity of cable")
),
)
else:
if results.status == DialogTurnStatus.Complete:
number_result = results.result
await turn_context.send_activity(
MessageFactory.text(
f"You asked me for '{number_result}' meters of cable."
)
)
await conver_state.save_changes(turn_context)
adapter = TestAdapter(exec_test)
test_flow = TestFlow(None, adapter)
test_flow2 = await test_flow.send("Hello")
test_flow3 = await test_flow2.assert_reply("Enter quantity of cable")
test_flow4 = await test_flow3.send("Give me twenty meters of cable")
await test_flow4.assert_reply("You asked me for '20' meters of cable.")
async def test_number_prompt_retry(self):
async def exec_test(turn_context: TurnContext) -> None:
dialog_context: DialogContext = await dialogs.create_context(turn_context)
results: DialogTurnResult = await dialog_context.continue_dialog()
if results.status == DialogTurnStatus.Empty:
options = PromptOptions(
prompt=Activity(type=ActivityTypes.message, text="Enter a number."),
retry_prompt=Activity(
type=ActivityTypes.message, text="You must enter a number."
),
)
await dialog_context.prompt("NumberPrompt", options)
elif results.status == DialogTurnStatus.Complete:
number_result = results.result
await turn_context.send_activity(
MessageFactory.text(f"Bot received the number '{number_result}'.")
)
await convo_state.save_changes(turn_context)
adapter = TestAdapter(exec_test)
convo_state = ConversationState(MemoryStorage())
dialog_state = convo_state.create_property("dialogState")
dialogs = DialogSet(dialog_state)
number_prompt = NumberPrompt(
dialog_id="NumberPrompt", validator=None, default_locale=Culture.English
)
dialogs.add(number_prompt)
step1 = await adapter.send("hello")
step2 = await step1.assert_reply("Enter a number.")
step3 = await step2.send("hello")
step4 = await step3.assert_reply("You must enter a number.")
step5 = await step4.send("64")
await step5.assert_reply("Bot received the number '64'.")
async def test_number_uses_locale_specified_in_constructor(self):
# Create new ConversationState with MemoryStorage and register the state as middleware.
conver_state = ConversationState(MemoryStorage())
# Create a DialogState property, DialogSet and register the WaterfallDialog.
dialog_state = conver_state.create_property("dialogState")
dialogs = DialogSet(dialog_state)
# Create and add number prompt to DialogSet.
number_prompt = NumberPrompt(
"NumberPrompt", None, default_locale=Culture.Spanish
)
dialogs.add(number_prompt)
async def exec_test(turn_context: TurnContext) -> None:
dialog_context = await dialogs.create_context(turn_context)
results = await dialog_context.continue_dialog()
if results.status == DialogTurnStatus.Empty:
await dialog_context.begin_dialog(
"NumberPrompt",
PromptOptions(
prompt=MessageFactory.text(
"How much money is in your gaming account?"
)
),
)
else:
if results.status == DialogTurnStatus.Complete:
number_result = results.result
await turn_context.send_activity(
MessageFactory.text(
f"You say you have ${number_result} in your gaming account."
)
)
await conver_state.save_changes(turn_context)
adapter = TestAdapter(exec_test)
test_flow = TestFlow(None, adapter)
test_flow2 = await test_flow.send("Hello")
test_flow3 = await test_flow2.assert_reply(
"How much money is in your gaming account?"
)
test_flow4 = await test_flow3.send("I've got $1.200.555,42 in my account.")
await test_flow4.assert_reply(
"You say you have $1200555.42 in your gaming account."
)
async def test_number_prompt_validator(self):
async def exec_test(turn_context: TurnContext) -> None:
dialog_context = await dialogs.create_context(turn_context)
results = await dialog_context.continue_dialog()
if results.status == DialogTurnStatus.Empty:
options = PromptOptions(
prompt=Activity(type=ActivityTypes.message, text="Enter a number."),
retry_prompt=Activity(
type=ActivityTypes.message,
text="You must enter a positive number less than 100.",
),
)
await dialog_context.prompt("NumberPrompt", options)
elif results.status == DialogTurnStatus.Complete:
number_result = int(results.result)
await turn_context.send_activity(
MessageFactory.text(f"Bot received the number '{number_result}'.")
)
await conver_state.save_changes(turn_context)
# Create new ConversationState with MemoryStorage and register the state as middleware.
conver_state = ConversationState(MemoryStorage())
# Create a DialogState property, DialogSet and register the WaterfallDialog.
dialog_state = conver_state.create_property("dialogState")
dialogs = DialogSet(dialog_state)
# Create and add number prompt to DialogSet.
async def validator(prompt_context: PromptValidatorContext):
result = prompt_context.recognized.value
if 0 < result < 100:
return True
return False
number_prompt = NumberPrompt(
"NumberPrompt", validator, default_locale=Culture.English
)
dialogs.add(number_prompt)
adapter = TestAdapter(exec_test)
step1 = await adapter.send("hello")
step2 = await step1.assert_reply("Enter a number.")
step3 = await step2.send("150")
step4 = await step3.assert_reply(
"You must enter a positive number less than 100."
)
step5 = await step4.send("64")
await step5.assert_reply("Bot received the number '64'.")
async def test_float_number_prompt(self):
async def exec_test(turn_context: TurnContext) -> None:
dialog_context = await dialogs.create_context(turn_context)
results = await dialog_context.continue_dialog()
if results.status == DialogTurnStatus.Empty:
options = PromptOptions(
prompt=Activity(type=ActivityTypes.message, text="Enter a number.")
)
await dialog_context.prompt("NumberPrompt", options)
elif results.status == DialogTurnStatus.Complete:
number_result = float(results.result)
await turn_context.send_activity(
MessageFactory.text(f"Bot received the number '{number_result}'.")
)
await conver_state.save_changes(turn_context)
# Create new ConversationState with MemoryStorage and register the state as middleware.
conver_state = ConversationState(MemoryStorage())
# Create a DialogState property, DialogSet and register the WaterfallDialog.
dialog_state = conver_state.create_property("dialogState")
dialogs = DialogSet(dialog_state)
# Create and add number prompt to DialogSet.
number_prompt = NumberPrompt(
"NumberPrompt", validator=None, default_locale=Culture.English
)
dialogs.add(number_prompt)
adapter = TestAdapter(exec_test)
step1 = await adapter.send("hello")
step2 = await step1.assert_reply("Enter a number.")
step3 = await step2.send("3.14")
await step3.assert_reply("Bot received the number '3.14'.")
async def test_number_prompt_uses_locale_specified_in_activity(self):
async def exec_test(turn_context: TurnContext):
dialog_context = await dialogs.create_context(turn_context)
results = await dialog_context.continue_dialog()
if results.status == DialogTurnStatus.Empty:
options = PromptOptions(
prompt=Activity(type=ActivityTypes.message, text="Enter a number.")
)
await dialog_context.prompt("NumberPrompt", options)
elif results.status == DialogTurnStatus.Complete:
number_result = float(results.result)
self.assertEqual(3.14, number_result)
await conver_state.save_changes(turn_context)
conver_state = ConversationState(MemoryStorage())
dialog_state = conver_state.create_property("dialogState")
dialogs = DialogSet(dialog_state)
number_prompt = NumberPrompt("NumberPrompt", None, None)
dialogs.add(number_prompt)
adapter = TestAdapter(exec_test)
step1 = await adapter.send("hello")
step2 = await step1.assert_reply("Enter a number.")
await step2.send(
Activity(type=ActivityTypes.message, text="3,14", locale=Culture.Spanish)
)
async def test_number_prompt_defaults_to_en_us_culture(self):
async def exec_test(turn_context: TurnContext):
dialog_context = await dialogs.create_context(turn_context)
results = await dialog_context.continue_dialog()
if results.status == DialogTurnStatus.Empty:
options = PromptOptions(
prompt=Activity(type=ActivityTypes.message, text="Enter a number.")
)
await dialog_context.prompt("NumberPrompt", options)
elif results.status == DialogTurnStatus.Complete:
number_result = float(results.result)
await turn_context.send_activity(
MessageFactory.text(f"Bot received the number '{number_result}'.")
)
await conver_state.save_changes(turn_context)
conver_state = ConversationState(MemoryStorage())
dialog_state = conver_state.create_property("dialogState")
dialogs = DialogSet(dialog_state)
number_prompt = NumberPrompt("NumberPrompt")
dialogs.add(number_prompt)
adapter = TestAdapter(exec_test)
step1 = await adapter.send("hello")
step2 = await step1.assert_reply("Enter a number.")
step3 = await step2.send("3.14")
await step3.assert_reply("Bot received the number '3.14'.")