Chai: Check that string contains multiple other strings

Created on 2 Nov 2016  路  18Comments  路  Source: chaijs/chai

Hello everyone!

First of all, thanks for a great library ;)

Second of all, please give me an advice - is there a nicer way to test that string contains multiple other strings than chaining .and.contains(...)?

assertion-request medium-size question

Most helpful comment

To whom it may concern

// Check for all substrings
expect(string).to.satisfy(string =>
  ['substring1', 'substring2'].every(bit => string.includes(bit))
);

```js
// Check for some substrings
expect(string).to.satisfy(string =>
['substring1', 'substring2'].some(bit => string.includes(bit))
);

You can also create some helpers:
```js
const CheckForAll = bits => string => bits.every(bit => string.includes(bit));
const CheckForSome = bits => string => bits.some(bit => string.includes(bit));

// In your test
const containsAll = CheckForAll(['sub1', 'sub2']);
expect(string).to.satisfy(containsAll);

const containsSome = CheckForSome(['sub1', 'sub2']);
expect(string).to.satisfy(containsSome);

All 18 comments

Hi @postatum, thanks for the issue! 馃槃
Currently I think there's no other way to do it. You either use and to chain assertions or create multiple different assertions. However, your suggestions seems useful and maybe we could change the include assertion behavior to allow users to pass an array of strings that should be contained within another string.

What does the rest of the team think? Is it useful for our users? Should we implement it?

I feel like we should have .{include,contain}.{all,any}.strings (same way we have .keys) in the Chai's core. Having them will likely save users from extra regular expressions (which are error prone because of escaping).

@shvaikalesh agreed! Great idea, I think that way we will still be able to maintain modularity and follow the same pattern throughout the whole code. +1 for that!

We have long-term plans to migrate Brunch's e2e tests back to mocha + chai and would benefit from this too, as other folks doing bundlers/transpilers.

@shvaikalesh @lucasfcosta Does this mean that we will be able to write any of the following statements when this feature is implemented?

expect(myArray).to.include.any.strings("str1","str2");
expect(myArray).to.include.all.strings("str1","str2");

This would make the code look clean when there is an error code kind of scenario that needs to be tested.

:+1: for this request

Yep, that is what we are suggesting. Would love to hear what other awesome maintainers think. @keithamus @meeber @vieiralucas

@vivganes Just to be clear, since you used myArray in your latest examples: If you're matching strings inside of an array, then you can use the existing .members assertion:

expect(myArray).to.include.members(["str1","str2"]);
expect(myArray).to.have.members(["str1","str2"]);

But if you're searching for strings within a string, then yes, we'd need the not-yet-implemented .strings assertion:

expect(myString).to.include.any.strings("str1","str2");
expect(myString).to.include.all.strings("str1","str2");

So since 3 of us agreed on this already I'll tag this as medium-fix and assertion-request. If anyone disagrees, please let us know.
Would you like to implement it @postatum? If you want to do so you could take a look at how the keys assertion works and implement something like that, as @shvaikalesh suggested.
If you don't feel like doing a PR for that, no problem! Just let us know so others can work on that!

Also, thanks for the awesome suggestion!

@lucasfcosta thanks! I'll take a look this weekend and let you know how things are going.

Hello @postatum, thank you for your issue!

I'm very happy to see that you are interested in implementing it.
We are very interested in helping anyone to contribute, so if you have any problem with the code base or if you need help with anything while you are implementing this feature, just come tu us.
You can post here on the issue or you can open a PR as a WIP and ask there.

Thank you so much for willing to contribute to chai :smile:

Hi @postatum have you had a chance to look into this more?

Hi Lucas. Sorry, I was short on time last few weeks. Will take a look this weekend.

Hi,

Can anyone suggest a solution to a problem i've.

i've the following inputs and want to check if str exists in it or not
{'let', 'code'}

'letcode' - T
'codelet' - T
'letletlet' -T
'letscode' - F

To whom it may concern

// Check for all substrings
expect(string).to.satisfy(string =>
  ['substring1', 'substring2'].every(bit => string.includes(bit))
);

```js
// Check for some substrings
expect(string).to.satisfy(string =>
['substring1', 'substring2'].some(bit => string.includes(bit))
);

You can also create some helpers:
```js
const CheckForAll = bits => string => bits.every(bit => string.includes(bit));
const CheckForSome = bits => string => bits.some(bit => string.includes(bit));

// In your test
const containsAll = CheckForAll(['sub1', 'sub2']);
expect(string).to.satisfy(containsAll);

const containsSome = CheckForSome(['sub1', 'sub2']);
expect(string).to.satisfy(containsSome);

@postatum thank you very much for this issue and thanks everyone for giving us our input, especially @0vidiu for your examples! 馃槃

For v5 we have talked about deprecating .contains, .have.string and .include in order to keep the API uniform, simple and consistent with the native equivalents.

I have referenced your issue at the roadmap and we'll make sure to make it easier for everyone to assert on substrings in the future.

I'll close this for now due to house-cleaning. I look forward to seeing your contributions again on v5. Thank you!

It would be cool if this worked
expect(envString).to.eventually.include.any.string('local', 'dev')

will this get implemented before the 2020 elections?

['str1', 'str2'].forEach((item) => {
  expect(testedString).to.contains(item);
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

xareelee picture xareelee  路  3Comments

meeber picture meeber  路  4Comments

danthegoodman picture danthegoodman  路  3Comments

endymion00 picture endymion00  路  3Comments

jockster picture jockster  路  4Comments