Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inclusion/containment semantics #97

Closed
jfirebaugh opened this issue Sep 22, 2012 · 8 comments
Closed

inclusion/containment semantics #97

jfirebaugh opened this issue Sep 22, 2012 · 8 comments

Comments

@jfirebaugh
Copy link
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.

Options:

  • 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.

Thoughts?

@domenic
Copy link
Contributor

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.

@logicalparadox
Copy link
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.

@jfirebaugh
Copy link
Member Author

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.

@logicalparadox
Copy link
Member

Agreed.

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

@jfirebaugh
Copy link
Member Author

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
Copy link

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: https://github.com/elliotf/chai-fuzzy 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'});

or

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.

@tubalmartin
Copy link

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

@keithamus
Copy link
Member

Closing this for a more focussed discussion in #644

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants