最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Boolean disjunction (OR) using mocha and chai - Stack Overflow

programmeradmin2浏览0评论

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)
Share Improve this question edited Jan 2, 2015 at 9:01 ajaest asked Dec 31, 2014 at 12:03 ajaestajaest 6376 silver badges14 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

You 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';
});
发布评论

评论列表(0)

  1. 暂无评论