I have the following scenario in which I have to check that an URL was build correctly provided some query arguments. I do not expect the system to apply an specific order in the rendered URL, so I came with the following test case which I expected to work:
it('test that url is built correctly', function () {
var args = {
arg1: 'value1',
arg1: 'value2'
};
var rendered_url = render_url(args);
expect(rendered_url).to.equal('/my/url?arg1=value1&arg2=value2')
.or.to.equal('/my/url?arg2=value2&arg1=value1')
;
});
I was pretty surprised to the or
chain to not exists as it makes the statement construction process tidy and cozy.
I know I can workaround this in many ways (for example, using satisfy
), but I wonder:
- Whether I cannot find the pattern to achieve in a similar way what I want in the documentation(I have read it thoroughly)...
- ... or whether there exists a good reason to not include this construction in chai...
- ... or whether there exists an alternative way to achieve a construction similar to the one in the example (tweaking, other frameworks, etc)
I have the following scenario in which I have to check that an URL was build correctly provided some query arguments. I do not expect the system to apply an specific order in the rendered URL, so I came with the following test case which I expected to work:
it('test that url is built correctly', function () {
var args = {
arg1: 'value1',
arg1: 'value2'
};
var rendered_url = render_url(args);
expect(rendered_url).to.equal('/my/url?arg1=value1&arg2=value2')
.or.to.equal('/my/url?arg2=value2&arg1=value1')
;
});
I was pretty surprised to the or
chain to not exists as it makes the statement construction process tidy and cozy.
I know I can workaround this in many ways (for example, using satisfy
), but I wonder:
- Whether I cannot find the pattern to achieve in a similar way what I want in the documentation(I have read it thoroughly)...
- ... or whether there exists a good reason to not include this construction in chai...
- ... or whether there exists an alternative way to achieve a construction similar to the one in the example (tweaking, other frameworks, etc)
2 Answers
Reset to default 7You could use to.include
or .match
:
var chai = require("chai");
var expect = chai.expect;
var option1 = '/my/url?arg1=value1&arg2=value2';
var option2 = '/my/url?arg2=value2&arg1=value1';
var possible = [option1, option2];
var re = /^\/my\/url\?arg1=value1&arg2=value2|\/my\/url\?arg2=value2&arg1=value1$/;
it('1', function () {
var rendered_url = option1;
expect(possible).to.include(rendered_url);
expect(rendered_url).to.match(re);
});
it('2', function () {
var rendered_url = option2;
expect(possible).to.include(rendered_url);
expect(rendered_url).to.match(re);
});
it('3', function () {
var rendered_url = "foo";
expect(possible).to.include(rendered_url);
});
it('4', function () {
var rendered_url = "foo";
expect(rendered_url).to.match(re);
});
The first 2 tests will pass, the last 2 will fail.
I've not done it in this example but both possible
and re
could be generated by a function rather than hand-coding all possible permutations of arguments.
I suspect the reason that .or
is not in Chai is that it would plicate Chai's code quite a bit and make it more cumbersome to use for regular cases. Right now when .equal
is called, it knows it is terminal. If Chai allowed to use .or
, then .equal
could not know right away whether it is terminal or not. Even if you had something like expect(foo).to.equal(bar)
, the call to equal
cannot know that it is terminal. You'd have to do something like what some promises library do to signal that the code is finished with a promise and have a call saying "I'm done here" so it would look like expect(foo).to.equal(bar).end()
. I'm not saying it would be impossible but it would have wide-ranging repercussions.
You could do something like:
expect(rendrered_url).to.satisfy(function(url){
return url === '/my/url?arg1=value1&arg2=value2 || url === '/my/url?arg2=value2&arg1=value1';
});