IntentDialog matches only once at the start in bot framework - bots

I have a simple piece of code where I want to run a first run operation in the beginning and let the default dialog handle everything else. In the code below.
bot.dialog('/firstRun', [firstRun1])
function firstRun1(session) {
session.replaceDialog('/')
}
bot.dialog('/', new builder.IntentDialog()
.matches(/wishlist/, '/wishlist')
.matches(/exclusive/, '/exclusive')
.onDefault('/runCampaign')
)
bot.dialog('/wishlist', (session, args) => {
session.endDialog('Add to wishlist')
})
bot.dialog('/exclusive', (session, args) => {
session.endDialog('Exclusive')
})
bot.dialog('/runCampaign', [runCampaign1])
function runCampaign1(session) {
session.send('default')
}
My problem is right here. When the person types exclusive I believe the default dialog will run its matches and should ideally trigger exclusive no matter how many times but for some reason its not happening that way as per the screenshot below. Once a person types exclusive or wishlist at the start it always runs the default at the bottom, how can I fix this. Also how to share data commonly between the different match clauses in the IntentDialog, lets say I want to have some variable session.dialogData.name across the matches and the default
UPDATE 1
Instead of saying session.endDialog inside the 2 areas in my code above, I simply wrote session.send() without ending any dialogs and now nothing happens when i type exclusive or wishlist. Am I missing something?

You should always call session.endDialog if you want to return to the calling(previous) dialog.
In your first example:
|current dialog|user input|next dialog|
|first run |go | / |
| / |whishlist | / |
| / |freak |runCampaign|
|runCampaign |<any> |runCampaign|
as you didn't call session.endDialog in the runCampaign dialog, you will always be in it and on any user input the 'default' will be printed.
In you second example, you missed to type "whishlist", so you immediately got into the runCampaign dialog. So, you changes to send there not called. But if you were typed 'whislist' as in the first example before "freak", you would have gotten into wishlist and you would always have printed "Added to wishlist" on any input.

Related

How to assert an array not containing certain value when using it.each in Jest

I'm writing a suite of tests utilising it.each as there are several conditions.
One of the test assertions is that a function was called/not called with an array containing one particular value. The function can be called with other values not associated with my test. I only care if it was or wasn't called with one specific value. E.g:
expect(myFunction).toHaveBeenCalledWith(
expect.arrayContaining([assertion])
);
Through the course of running my unit test, myFunction may have been called with ["blue", "green"]. I only care about whether "blue" is present or not. I do not care whether "green" is there. It is irrelevant to my test.
How can I correctly assert this in an it.each test?
describe("when there is a save count", () => {
it.each`
condition | assertion
${false} | ${null} // this is where blue isn't called
${true} | ${"blue"} // this is where blue is called
`("Instance of blue in the function arguments should be $condition", ({ assertion }) => {
fireFunctions(defaultArgs);
expect(myFunction).toHaveBeenCalledWith(
expect.arrayContaining([assertion]) // this is wrong but not sure
);
});
});
My example shows that in the case where I don't want "blue" to be present in the array I've set assertion to null. I know this isn't right but I just don't know what I should be doing. The result of this test comes out as thus:
Expected: ArrayContaining [null]
Received: ["green"]
So although it's worked in that "blue" isn't there, because "green" is there the Received doesn't match the Expected.
I toyed around with the concept of .any to achieve a result, but the problem is that using expect.any(String) provides a false positive because "green" is also a string.
How can I create an it.each that works with the assertions laid out?

How do I see the returned value(s) of a function in Alloy?

I'm trying to understand how functions work in Alloy, and an important part of that is testing them. For example I've got this code:
open util/ordering[Time] // enforces total order on Time
sig Time {} // instances denote timestamps
sig File {
time : Time // every file has exactly one timestamp
}
fun getTime[F : set File] : Time {
{t : Time | some f : F | all x : F | f.time = t && gte[f.time,x.time]}
}
The getTime function is meant to return the time value of the file(s) with the greatest timestamp, out of the given set of files. I've made the function, and I believe it should work as intended, but I have no clue how to actually test that. I know I can run functions in Alloy, but I can't figure out how to create a sample set of files to use as input. Whenever I do manage to get something to run, nowhere in the resulting visualization does it show what the function outputted.
In the visualization, you can open the "Evaluator" with a button in the toolbar.
There you can enter stuff like:
univ
to get a list of all atoms. And:
getTime[File$0]
to evaluate a function.

MFC Edit Control EN_KILLFOCUS issue

I am using Visual Studio 2013 and making MFC Dialog based application. I am running into strange issue with Kill Focus of Edit Control.
Please see below:
==========================================================================
In my application, I have two Edit Controls on Dialog Box.
1st Edit Control -> IDC_EDIT_QUALITY1
2nd Edit Control -> IDC_EDIT_QUALITY2
I have handled both's EN_KILLFOCUS event to validate the value.
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
ON_EN_KILLFOCUS(IDC_EDIT_QUALITY1, &CTestDlg::OnQuality1EditKillFocus)
ON_EN_KILLFOCUS(IDC_EDIT_QUALITY2, &CTestDlg::OnQuality2EditKillFocus)
END_MESSAGE_MAP()
void CTestDlg::OnQuality1EditKillFocus()
{
ValidateQualityParams(IDC_EDIT_QUALITY1);
}
void CTestDlg::OnQuality2EditKillFocus()
{
ValidateQualityParams(IDC_EDIT_QUALITY2);
}
#define MIN_QUALITY_VALUE 1
#define MAX_QUALITY_VALUE 100
void CTestDlg::ValidateQualityParams(int qualityParamID)
{
CString strQuality1;
if (IDC_EDIT_QUALITY1 == qualityParamID)
{
m_ctrlQuality1.GetWindowText(strQuality1);
if ((_ttoi(strQuality1) < MIN_QUALITY_VALUE) || (_ttoi(strQuality1) > MAX_QUALITY_VALUE))
{
CString strMessage;
strMessage.Format(_T("Quality1 value must be between %d to %d."), MIN_QUALITY_VALUE, MAX_QUALITY_VALUE);
**AfxMessageBox(strMessage);**
m_ctrlQuality1.SetSel(0, -1);
m_ctrlQuality1.SetFocus();
return;
}
}
CString strQuality2;
if (IDC_EDIT_QUALITY2 == qualityParamID)
{
m_ctrlQuality2.GetWindowText(strQuality2);
if ((_ttoi(strQuality2) < MIN_QUALITY_VALUE) || (_ttoi(strQuality2) > MAX_QUALITY_VALUE))
{
CString strMessage;
strMessage.Format(_T("Quality2 value must be between %d to %d."), MIN_QUALITY_VALUE, MAX_QUALITY_VALUE);
AfxMessageBox(strMessage);
m_ctrlQuality2.SetSel(0, -1);
m_ctrlQuality2.SetFocus();
return;
}
}
}
Now, the issue happens when, after changing the value in 1st Edit Control (IDC_EDIT_QUALITY1), say entering 0 in it and pressing TAB key, the flow goes as below:
void CTestDlg::OnQuality1EditKillFocus() is called.
It calls ValidateQualityParams(IDC_EDIT_QUALITY1)
Inside ValidateQualityParams, it goes to if (IDC_EDIT_QUALITY1 == qualityParamID) condition.
As the value I entered is less than MIN_QUALITY_VALUE, so it shows the Message by calling AfxMessageBox.
- Now, even from the callstack of AfxMessageBox, it hits void CTestDlg::OnQuality2EditKillFocus() internally.
Although callstack of OnQuality1EditKillFocus is NOT finished yet, OnQuality2EditKillFocus gets called from the callstack of AfxMessageBox.
I don't understand the cause of this issue. Has anyone encountered such issue before?
In my resource.h, I have two distinct values for IDC_EDIT_QUALITY1 and IDC_EDIT_QUALITY2
#define IDC_EDIT_QUALITY1 1018
#define IDC_EDIT_QUALITY2 1020
Please help on this issue.
I believe the EN_KILLFOCUS notification for the IDC_EDIT_QUALITY2 control you are receiving is caused not by the m_ctrlQuality1.SetFocus() call, but instead by the AfxMessageBox() call.
When you press the [Tab] key IDC_EDIT_QUALITY1 loses the focus, and IDC_EDIT_QUALITY2 gets the focus. Then you receive the EN_KILLFOCUS notification for IDC_EDIT_QUALITY1. You display the error-message, which causes the application to "yield" (start processing messages again), while the message-box is displayed. The m_ctrlQuality1.SetFocus() call won't take place before the AfxMessageBox() returns, ie before you close the message-box, and therefore the EN_KILLFOCUS notification for IDC_EDIT_QUALITY2 can't be the result of that call. I guess it's the result of displaying the message-box (IDC_EDIT_QUALITY2 has got the focus, but the message-box makes it lose it).
You may work around it by adding a memeber variable, as Staytuned123 suggested, but in a different setting: name it, say m_bKillFocusProcessing, and set it to TRUE while you are processing ANY EN_KILLFOCUS notification (AfxMessageBox() plus SetFocus()), and to FALSE when you are done processing it; if it's already TRUE exit without doing anything. That is, only one EN_KILLFOCUS notification may be processed at a time.
However, such a user-interface (displaying a message-box on exiting a field) is rather weird. And why reinvent the wheel and not instead use the DDX/DDV feature, which MFC already offers? You can define member variables associated with controls, and perform various checks, including range-check. Call UpdateData(TRUE) to perform the checks (for all controls on the dialog) and transfer the data to the member variables. Or you can put some error-displaying controls (usually in red color), activated when an error is found, like in .net or the web.
When you pressed TAB key, IDC_EDIT_QUALITY2 got focus. But because value entered was out of bound, the program called m_ctrlQuality1.SetFocus(), which in turn caused OnQuality2EditKillFocus() to get called.
Add a member variable says m_bQuality1OutOfBound and set it to true right before calling m_ctrlQuality1.SetFocus(). In OnQuality2EditKillFocus(), when m_bQuality1OutOfBound is true, set it to false and don't call ValidateQualityParams(IDC_EDIT_QUALITY2).

Conditional Inputs?

I'm trying to write a cucumber test for part of our application (I'm completely new to cucumber, and writing acceptance tests really), and I have a step in the test, which I want to do one of 2 different things. I want it to either check for a specific value, or check for a system default value.
This is what I came up with
Scenario Outline: English News
Given with the locale is set to '<language>'
When a user views the page
Then they see the <image> image
Examples:
| language | image |
| en-gb | default |
| fr | "french.png" |
This then hits one of 2 different step definitions,
#And("^they see the default image$")
public void defaultImage() throws Throwable {
// check for system default
}
#And("^they see the \"(.*)\" image$")
public void customImage(String image) throws Throwable {
// check for specific value from the input
}
Is this the correct way to do this? My TL has suggested that I should actually only have the one step def, and pass "default" as the input, and then do a conditional check inside the step def, like this:
#And("^they see the \"(.*)\" image$")
public void checkImage(String image) throws Throwable {
if ("default".equals(image)){
// check for system default
} else {
// check for specific value from the input
}
}
Which is the correct way to do this? Any help is greatly appreciated.
your default image must have a real name, right ? so why not validating its real name ? because "default" could be anything so not everyone may understand the same thing.
If you do this, indeed you need only one step def. I wouldn't put an if check, I would assert the real name. You can maybe add a comment in your example table saying that the first value is the default, so that it's clear for everyone in your team.

Nodejs node-sqlite3 run callback not working

I am trying to perform a delete of a row in sqlite db using nodejs and node-sqlite3 package.
When I run the delete command, and manually check the entries, I can see that the query successfully deleted that row but I cant seem to write the code that confirms this.
This is the query
db.run("DELETE FROM Table1 WHERE id=? AND username=?", [id, user], function(error) {
console.log(error);
});
Regardless of a wrong or right input, it outputs null to the console. If the right details are given, it deletes it and prints null, if wrong id and user are given, it still prints null.
Any ideas on what might be wrong?
Thanks
To my prevoius question, the problem was that I've used fat arrow for callback declaration. From javascript documentation I've discovered that in arrow function (fat arrow ), this has lexical scope and so this result undefined and not valued as in library documentation said. Using otherwise anonimous function, this is bounded in dynamic scope and so this.changes is valued.
Now, with code as below, is ok:
var sql = 'update recipes set stars = stars + 1 where id = ?';
db.run(sql,
[
1 // id = 1 execute update - if id = 11111 do nothing
], function(err) {
if(err)
throw err;
console.log("VALUE CHANGES: " + this.changes + " - " + util.inspect(this, { showHidden: false, depth: null }));
if(this.changes == 1)
console.log("WORK DONE");
else
console.log("NOTHING DONE");
});
Here more explanations: https://github.com/mapbox/node-sqlite3/issues/606
There is nothing wrong in the node and node-sqlite3 behaviour here.
Here are two parts to explain first regarding node and other regarding Sqlite.
Node
Your callback is getting called after execution of the statement. So nothing wrong here, since your callback is getting called (as proved by 'null' as output).
Sqlite
Delete query in Sqlite deletes if condition given in where clause evaluates to true, otherwise nothing is deleted.
Referring from node-sqlite3 documentation's Database#run api:
callback (optional): If given, it will be called when an error occurs
during any step of the statement preparation or execution, and after
the query was run. If an error occurred, the first (and only)
parameter will be an error object containing the error message. If
execution was successful, the first parameter is null.
So, in your case query execution succeeds without any error, resulting in error argument to callback function null as you see in output.
Further, if you want to check if any row was actually removed, you can use changes property as mentioned in the documentation:
If execution was successful, it contains two properties named "lastID"
and "changes" which contain the value of the last inserted row ID and
the number of rows affected by this query respectively. Note that
"lastID" only contains valid information when the query was a
successfully completed INSERT statement and "changes" only contains
valid information when the query was a successfully completed UPDATE
or DELETE statement. In all other cases, the content of these
properties is inaccurate and should not be used. The .run() function
is the only query method that sets these two values; all other query
methods such as .all() or .get() don't retrieve these values.
Hope it helps...
I had similar problem, callbacks just would not fire. Period. The problem was that elsewhere I was calling process.exit(1), so my code was exiting before the the callbacks had a chance to return.
Search for process.exit, that may (or may not) save you hours of debugging and blaming sqlite :)
Off the topic: What bugs my mind is why they all-cap ID in lastID. It's not like it's an abbreviation like SQL or USA. It stands for Identification, which is one word.

Resources