I'm quite new in the world of Javascript and asynchronous and it seems that both are giving me headaches.
So, I have a 3rd party client API that has the following async method getItem(id)
Now I'm trying to determine the status for a parent item based on it's children:
getStatus = function(ids) {
var failedCount = 0;
var successCount = 0;
var warningCount = 0;
ids.forEach(function(id) {
//calling the async function
getItem(id).then(function(item) {
var state = item.State;
if(state == "Success") {
successCount++;
} else if(state == "Failed") {
failedCount++;
} else if(state == "Warning") {
warningCount++;
}
});
});
if(failedCounter > 0) {
return "Failed";
} else if(warningCounter > 0) {
return "Warning";
} else if(successCounter == ids.length) {
return "Success";
} else {
return "Not run yet";
}
}
Then, to make sure that I won't break anything on the way, I decided to go with some integration tests, so I settled for QUnit and qunit-parameterize:
QUnit.cases([
{
title : "Success, Failed => Failed",
ids : [1,2],
expectedItemStateAfter : "Failed"
}
]).test( "", function( params, assert ) {
var done = assert.async(2);
setTimeout(function() {
var value = getStatus(params.ids);
assert.equal(value, params.expectedItemStateAfter);
done();
}, 2000);
});
Tried to tweak the setTimeout timeout, tried with assert.async(2) and assert.async();, the default value per QUnit per their documentation, but no avail, the end result is still the same everytime and even after a bunch of readings and trying to understand I have no idea what I'm doing wrong:
1. failed @ 2004 ms
Expected: "Failed"
Result: undefined
Diff: "Failed" undefined
Your getStatus function is returning a result before any of the async calls resolve. You need to make getStatus return a promise that resolves when all of the other promises resolve using Promise.all:
var getStatus = function(ids) {
var failedCount = 0;
var successCount = 0;
var warningCount = 0;
return Promise.all(ids.map(function(id) {
return getItem(id).then(function(item) {
var state = item.State;
if (state === "Success") {
successCount++;
} else if (state === "Failed") {
failedCount++;
} else if (state === "Warning") {
warningCount++;
}
});
})).then(function() {
if (failedCounter > 0) {
return "Failed";
} else if (warningCounter > 0) {
return "Warning";
} else if (successCounter === ids.length) {
return "Success";
} else {
return "Not run yet";
}
});
};
Then you will need to tweak the testing code so that it uses the promise instead of a setTimeout. Note that you can return a thenable object from the QUnit.test callback and it will automatically handle the resolving of a Promise.
QUnit.cases([
{ title: "Success, Failed => Failed", ids: [1, 2], expectedStatus: "Failed" }
]).test("getStatus() test", function(params, assert) {
return getStatus(params.ids).then(function(value) {
assert.equal(value, params.expectedStatus);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With