Testing an extension to expect.js - tdd

I'm writing some expect.js matchers and I'd like to test the matchers themselves. So I want to write positive and negative tests. Let's say I've written
toContainItem(name);
used like this;
expect(femaleNames).toContainItem('Brad'); // test fails
expect(femaleNames).toContainItem('Angelina'); // test passes
What I want to do is write a test for the negative case, like so;
it('should fail if the item is not in the list', function() {
expect(function() {
expect(femaleNames).toContainItem('Brad');
}).toFailTest('Could not find "Brad" in the array');
});
I'm not sure how to run my failing test code in an environment where it doesn't fail the containing test. Is this possible?
EDIT: Based on Carl Manaster's answer, I've come up with an extension to expect, allowing the code above to work;
expect.extend({
toFailTest(msg) {
let failed = false;
let actualMessage = "";
try
{
this.actual();
}
catch(ex)
{
actualMessage = ex.message;
failed = true;
}
expect.assert(failed, 'function should have failed exception');
if(msg) {
expect.assert(actualMessage === msg, `failed test: expected "${msg}" but was "${actualMessage}"`);
}
}
});

I would think you could wrap the inner expect in a try/catch block, where you clear a failure variable in the catch clause, then make your actual assertion about the value of the variable.
let failed = true;
try {
expect(femaleNames).toContainItem('Brad');
} catch (e) {
failed = false;
}
expected(failed).toBe(false);

Related

getting XMP File does not have a constructor error through ExtendScript

I am using In Design CC 2019, on my Mac OS. When I am trying to get XMP data for my .indd (InDesign document) using ExtendScript.
I am currently getting the error like this:
XMPFile Does not have a constructor.
Below is my script.
// load XMP Library
function loadXMPLibrary(){
if ( ExternalObject.AdobeXMPScript){
try{ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');}
catch (e){alert('Unable to load the AdobeXMPScript library!'); return false;}
}
return true;
}
var myFile= app.activeDocument.fullName;
// check library and file
if(loadXMPLibrary() && myFile != null){
xmpFile = new XMPFile(myFile.fsName, XMPConst.FILE_INDESIGN, XMPConst.OPEN_FOR_UPDATE);
var myXmp = xmpFile.getXMP();
}
if(myXmp){
$.writeln ('sucess')
}
There's an issue with your codes logic, you need to make the following change:
Add the Logical NOT operator (i.e. !) to the condition specified for your if statement in the body of your loadXMPLibrary function.
function loadXMPLibrary(){
if (!ExternalObject.AdobeXMPScript) { // <--- Change to this
// ^
try {ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');}
catch (e){alert('Unable to load the AdobeXMPScript library!'); return false;}
}
return true;
}
You need to add this because currently your if statement checks whether the condition is truthy, i.e. it checks whether ExternalObject.AdobeXMPScript is true. This will always remain false, until the AdobeXMPScript library has been loaded, therefore you're code that actually loads the library never gets executed.
Revised script:
For clarity here is the complete revised script:
// load XMP Library
function loadXMPLibrary() {
if (!ExternalObject.AdobeXMPScript) {
try{ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');}
catch (e){alert('Unable to load the AdobeXMPScript library!'); return false;}
}
return true;
}
var myFile= app.activeDocument.fullName;
// check library and file
if (loadXMPLibrary() && myFile !== null) {
xmpFile = new XMPFile(myFile.fsName, XMPConst.FILE_INDESIGN, XMPConst.OPEN_FOR_UPDATE);
var myXmp = xmpFile.getXMP();
}
if (myXmp){
$.writeln ('success')
}

Does Jasmine have an after-advice spy?

When spying on a method, we can either callThrough (use original implementation) or callFake (use a custom implementation).
What I want is a behaviour similar to callThrough but inspect/modify its return value before returning it to the caller.
So I can do something like this:
spyOn(foo, "fetch").and.afterCall(function(result) {
expect(result).toBeDefined();
result.bar = "baz";
return result;
});
Right now the simplest way is doing something like this:
var original = foo.fetch;
foo.fetch = function() {
var result = original.apply(this, arguments);
expect(result).toBeDefined();
result.bar = "baz";
return result;
}
Which is somewhat annoying because now I have to manually restore the spy instead of having the framework automatically does it for me.
Does Jasmine have an after-advice spy?
Generally: no.
You could extend the SpyStrategy object with such a function though:
this.callThroughAndModify = function(resultModifier) {
var result;
plan = function() {
result = originalFn.apply(this, arguments);
return resultModifier(result);
};
return getSpy();
};
You've to clone the above SpyStrategy file and insert that method.
Usage:
var obj = {
fn: function(a) { return a * 2; }
};
spyOn(obj, "fn").and.callThroughAndModify(function(result) {
console.log("Original result: ", result);
return 1;
});
expect(obj.fn(2)).toBe(1);
Drawbacks:
You've to replace the whole SpyStrategy.js
You've to load that script before Jasmine initializes the original SpyStrategy at boot

how to retry if cannot find element in Nightwatch

I want to retry if nightwatch does not click on an element. How can I do that?
I have the following code:
this.browser.isVisible('.signUp', function (result) {
if (result.value && result.length) {
for(var i = 0; i < 3; i += 1) {
this.browser.click(this.element.login.signInBtn);
var check = this.browser.url(function(result) {
// on login page
console.log(result);
if (result.value.indexOf("#login") !== -1) {
return false;
} else {
return true;
}
});
if (check) {
break;
}
}
}
}.bind(this));
-retries n will not run before and after function so this will not work as expected. You should try --suiteRetries n.
You can retry test cases with --retries command-line option. Example nightwatch --retries 2 will retry failed test case two additional times.
However I will not recommend you using that. I would first explore other options to make sure that element can be clicked. Like example waiting for it to become visible with waitForElementVisible
this.browser.waitForElementVisible(this.element.login.signInBtn, 1000);

What's the best approach to implement this algorithm?

What would be the best way to write an algorith like:
if (a) {
doA();
done();
}
else if (b) {
doB();
done();
}
else if (c) {
doC();
done();
}
another approach I thought:
done = true;
if (a) {
doA();
}
else if (b) {
doB();
}
else if (c) {
doC();
}
else {
done = false;
}
if (done) {
done();
}
Which is better? Is there another best approach?
Without any context, the most natural looking way for me is:
bool do_it(int condition)
{
switch (condition)
{
case a: doA(); return true;
case b: doB(); return true;
case c: doC(); return true;
default: return false;
}
}
// ...
if (do_it) done();
since it abstracts the logic of "if this whole stuff succeeds, then do call done()".
But there are many other ways to do this. Especially, if the number of conditions will likely grow in the future, I wouldn't do that at all.
Depends on how many conditions/actions are there and kind of language you are using.
OOP and polymorphysm could work nicely.
Use a switch statement, setting an isDone flag along the way, and call done() based on the flag.
If a,b and c are different complex conditional expressions then your first solution is the best. Maybe you can avoid the "else if" elements if this code is inside a function, like that:
private void doit() {
if (a) {
doA();
done();
return;
}
if (b) {
doB();
done();
return;
}
if (c) {
doC();
done();
return;
}
}
So for me it is much more a code style question.
I would write it as
var failed = false;
if (a) doA();
else if (b) doB();
else if (c) doC();
else failed = true;
if (!failed) done();
I don't like setting a variable like done first to true and later undoing it, because the work is not done before the conditional starts, so it looks illogical.
I also don't like the switch case option because the conditions 'a', 'b', 'c' are not necessarily mutually exclusive; the if ... else if ... else cascade supports non-exclusive conditions but switch() might not depending on the language. E.g. you can't convert cascading if ... else's to switch in C++.
I think it's definitely important to remove multiple call points to done() because that's redundancy and later a maintenance issue if done() e.g. gets parameters.
First, have one condition variable, not three. Second, I'd use a map of function pointers, with the condition variable as the key. Here's an example:
#!/usr/bin/env python
def doA():
pass
def doB():
pass
def doC():
pass
def done():
pass
a = 3
b = 6
c = 8
doers = {}
doers[a] = doA
doers[b] = doB
doers[c] = doC
condition = a
# this is now the entire "algorithm":
if condition in doers:
doers[condition]()
done()

Replacing nested if statements

This is related to a chapter from beautiful code.
And in that chapter I read about the nested ifs.
The author was talking about deeply nested ifs as originator of bugs and less readable.
And he was talking about replacing nested ifs with case statements and decision tables.
Can anybody illustrate how to remove nested ifs with case (select case) and decision tables ?
Well, not directly an answer to your question since you specifically ask about switch/case statements, but here is a similar question.
Invert “if” statement to reduce nesting
This talks about replacing nested if's with guard-statements, that return early, instead of progressively checking more and more things before settling on a return value.
One example I always try to do is replace heavily nested if's like this (actually this one's not too bad but I've seen them up to 8 or 9 levels deep in the wild):
if (i == 1) {
// action 1
} else {
if (i == 2) {
// action 2
} else {
if (i == 3) {
// action 3
} else {
// action 4
}
}
}
with this:
switch (i) {
case 1:
// action 1
break;
case 2:
// action 2
break;
case 3:
// action 3
break;
default:
// action 4
break;
}
I also try to keep the actions as small as possible (function calls are best for this) to keep the switch statement compressed (so you don't have to go four pages ahead to see the end of it).
Decision tables, I believe, are simply setting flags indicating what actions have to be taken later on. The "later on" section is simple sequencing of actions based on those flags. I could be wrong (it won't be the first or last time :-).
An example would be (the flag-setting phase can be complicated if's since its actions are very simple):
switch (i) {
case 1:
outmsg = "no paper";
genmsg = true;
mailmsg = true;
phonemsg = false;
break;
case 2:
outmsg = "no ink";
genmsg = true;
mailmsg = true;
phonemsg = false;
break;
default:
outmsg = "unknown problem";
genmsg = true;
mailmsg = true;
phonemsg = true;
break;
}
if (genmsg)
// Send message to screen.
if (mailmsg)
// Send message to operators email address.
if (phonemsg)
// Hassle operators mobile phone.
How about chained ifs?
Replace
if (condition1)
{
do1
}
else
{
if (condition2)
{
do2
}
else (condition3)
{
do3;
}
}
with
if (condition1) {
do1;
} else if (condition2) {
do2;
} else if (condition3) {
do3;
}
This is much like switch statement for complex conditions.
Make the condition into booleans and then write boolean expression for each case.
If the code was:
if (condition1)
{
do1
}
else
{
if (condition2)
{
do2
}
else (condition3)
{
do3;
}
}
One can write it as:
bool cond1=condition1;
bool cond2=condition2;
bool cond3=condition3;
if (cond1) {do1;}
if (!cond1 and cond2) {do2;}
if (!cond1 and cond3) {do2;}
For decision tables, please see my answer to this question, or better still read chapter 18 in Code Complete 2.
You can just break once a part of the validation failed for example.
function validate(){
if(b=="" || b==null){
alert("Please enter your city");
return false;
}
if(a=="" || a==null){
alert("Please enter your address");
return false;
}
return true;
}
Decision tables are where you store the conditional logic in a data structure rather than within the code itself.
So instead of this (using #Pax's example):
if (i == 1) {
// action 1
} else {
if (i == 2) {
// action 2
} else {
if (i == 3) {
// action 3
} else {
// action 4
}
}
}
you do something like this:
void action1()
{
// action 1
}
void action2()
{
// action 2
}
void action3()
{
// action 3
}
void action4()
{
// action 4
}
#define NUM_ACTIONS 4
// Create array of function pointers for each allowed value of i
void (*actions[NUM_ACTIONS])() = { NULL, action1, action2, action3 }
// And now in the body of a function somewhere...
if ((i < NUM_ACTIONS) && actions[i])
actions[i]();
else
action4();
If the possibilities for i are not low-numbered integers then you could create a lookup table instead of directly accessing the ith element of the actions array.
This technique becomes much more useful than nested ifs or switch statements when you have a decision over dozens of possible values.
If and switch statements are not purely OO. They are conditional procedural logic, but do a very good job! If you want to remove these statements for a more OO approach, combine the 'State' and 'Descriptor' patterns.
You might also consider using the Visitor pattern.
Nested if are equivalent to the logical operator AND
if (condition1)
{
if (function(2))
{
if (condition3)
{
// do something
}
}
}
Equivalent code:
if (condition1 && function(2) && condition3)
{
// do something
}
In both cases, when an expression evaluates false, the subsequent expression will not be evaluated. For example, if condition1 is false, the function() will not be called, and condition3 won't be evaluated.
Another example some languages allow is this
switch true{
case i==0
//action
break
case j==2
//action
break
case i>j
//action
break
}

Resources