Skip to content

inclusion/containment semantics #97

jfirebaugh opened this Issue Sep 22, 2012 · 8 comments

6 participants

Chai.js Assertion Library member

Chai's include/contain test equality via Array#indexOf, i.e. strictly.

I'm currently working on chai-jasmine (a compatibility library), and Jasmine's equivalent is toContain, which winds up using natural/deep/eql equality. It would be nice if this could be implemented entirely in terms of chai assertions and flags.


  • Provide natural/deep/eql semantics for the include/contain assertion if the deep flag is set, e.g.:

    expect(['A', {some:'object'}, 'C']).to.deep.contain({some:'object'})

    This phrasing suggests to me that things like expect({a: {b: {c: 'd'}}}).to.deep.contain({c: 'd'}) should also be supported. But then should arrays be recursively searched as well? (Jasmine's toContain does not support this.)

  • Introduce another flag, e.g. to.naturally.contain({some: 'object'}). But what's a good word?
  • Introduce another assertion. Again, what would it be called?
  • Give up and don't try to write the chai-jasmine toContain assertion in terms of chai assertions.


domenic commented Sep 22, 2012

Sinon introduced an interesting solution to this problem, called matchers. I don't think it's a great fit for Chai necessary, but it's food for thought.

Chai.js Assertion Library member

I like the deep contain as indicated in bullet point one. It provides a consistent language (deep equal and deep property) and it goes beyond the current offering of Jasmine.

Chai.js Assertion Library member

Jasmine has matchers as well. They can definitely be useful, but I've always wanted to see them implemented as an integration with a full-fledged external pattern-matching library, since those tend to be more fully fleshed out than a testing library addon.

I'll try to find some time to work up a PR for deep contain.

Chai.js Assertion Library member


Are there any pattern matching libraries that you like that could make a candidate for integration?

Chai.js Assertion Library member

I haven't seen one that I really loved. matches.js is the best I've seen. I dislike the fact that it's stringly typed, but that may be the best one can do in JS.

elliotf commented Oct 2, 2012

The idea of descending into an object to see if it has some values four layers deep smells like a bad test. The assertion should at least be able to tell in what level the expectation should reside.

To scratch this itch, I wrote: which leans on underscore

Would there be any interest in pulling this into main or getting it into better shape to be a better plugin?

The ".containsOneLike" matcher name is awkward; "contains" and "equal" are the natural names, but I don't (yet) want to replace the standard matchers.

What would be very nice is to have a modifier like "deeply" that changes the equality check:

var subject = {a: 'whatever'};
subject.should.loosely.equal({a: 'whatever'});


var subject = [{a: 'whatever'}];
subject.should.loosely.contain({a: 'whatever'});

Replace "loosely" with "sortOf" or "mostly", etc.

Event better would be to default to loose equality and be able to specify strict equality via "strictly" or some such.


A deep include/contain flag would be awesome (that's what Chai-Things plugin does in essence) for assertions on arrays of objects.

Even better would be to have atleast/atmost methods so we could express something like "This array should contain at least/at most n ocurrences of this item".

Some examples:

expect([1,2,3,1]).to.contain(1).atleast(1); // this would pass
expect([{a:1},{a:1},{a:2}]).to.deep.contain({a:1}).atmost(1); // this would fail
Chai.js Assertion Library member

Closing this for a more focussed discussion in #644

@keithamus keithamus closed this Mar 18, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.