I am creating an element (a router - but that is not important), that is scanning the DOM soon after it has attached for particular other custom elements. I certain cases it needs to throw an error and I want to test for these.
The test I constructed is not failing - but as far as I can make out the test has already failed before my element gets attached. I suspect it is the asynchronous nature of things.
Here is the snippet of the test in question. The test fixture in question contains elements that will cause one of the elements to fail after a 'dom-change' event happens (which it has a listener for) when it then scans the dom for other things.
it('should fail if two route elements both designate thenselves as home', function(done) {
var t= document.getElementById('multiple_home');
function multiple () {
t.create();
}
expect(multiple).to.throw(Error);
t.restore();
done();
});
I think the problem is related to the fact that the fixture is created in multiple, but hasn't yet failed by the time multiple exits. I am wondering if I can pass a Promise to expect - except I am not sure how to turn mulitple into a Promise to try it out.
I eventually found a way, but it requires instrumenting the element a bit to support this.
In the elements "created" callback I create a Promise and store the two functions to resolve and reject it in "this" variables - thus:-
this.statusPromise = new Promise(function(resolve,reject){
this.statusResolver = resolve;
this.statusRejector = reject;
}.bind(this));
In the DOM parsing section I use a try catch block like this
try {
//parse the dom throwing errors if anything bad happens
this.statusResolver('Any useful value I like');
} catch (error) {
this.statusRejector(error);
}
I then made a function that returns the promise
domOK: function() {
return this.statusPromise;
}
Finally in my test I was now able to test something like this (I load the fixture in each test, rather than a beforeEach, because I am using a different fixture for each test. I do clear it down again in an afterEach). Note the use of the .then and .catch functions from the Promise.
it('should fail if two route elements declare the same path name',function(done){
t = document.getElementById('multiple_path');
t.create();
r = document.getElementById('router')
r.domOK().then(function(status){
//We should not get here throw an error
assert.fail('Did not error - status is: ' + status);
done();
}).catch(function(error){
expect(error.message).to.equal('There are two nodes with the same name: /user');
done();
});