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

test array to include an object with a certain key: value #1024

Closed
Segev95 opened this issue Aug 10, 2017 · 7 comments
Closed

test array to include an object with a certain key: value #1024

Segev95 opened this issue Aug 10, 2017 · 7 comments

Comments

@Segev95
Copy link

Segev95 commented Aug 10, 2017

Hello,

As the title says we found our selves in a situation where we need to check if an array contains an element that one of his properties equals to something.

We tried and search for a couple of hours until we desided to raise an issue about it.
We were able to solve the problem like this:

const playersRegs = created.gameLog.filter(e => e.nameType === eventTypes.PlayerReg);
expect(playersRegs).to.have.lengthOf(1);

but we were hoping for something a bit like:

expect(created.gameLog).to.include.something.that.has.property('nameType', eventTypes.PlayerReg);

if we missed anything please let us know and if we didnt please consider adding this functionality ;)

@meeber
Copy link
Contributor

meeber commented Aug 10, 2017

I think the chai-things plugin does this, but unfortunately it doesn't currently support v4 (and might not even support v3.5).

Is the exact array index that contains the the desired property value not known ahead of time? I'd like to learn more about the use case that leads to this kind of test being written, as opposed to something like expect(created.gameLog[43]).to.have.property('nameType', eventTypes.PlayerReg);

On an unrelated note, I'd be careful about having a variable like eventTypes.PlayerReg as the expected property value. If .nameType and .PlayerReg both get renamed during some future refactor, then this test will become broken in such a way that it always passes because undefined === undefined. If replacing eventTypes.PlayerReg in the test with an explicit value isn't feasible, then this concern can be mitigated by having a separate test that asserts eventTypes.PlayerReg is the expected value or type.

@Segev95
Copy link
Author

Segev95 commented Aug 10, 2017

Hi meeber,
Thank you for your quick answer and for your note (I'll keep that in mind 👍 ).

Is the exact array index that contains the the desired property value not known ahead of time?

The array is events array. We represent each event as an object, and one of the properties this object has is 'nameType'. eventTypes is a constant json that contains all of our events 'nameType'.
The exact index is known ahead of time, but as you said - things can changed during some future refactor. We thought that it will be easier and more comfortable if we could just search for this property in the entire array's objects.

@meeber
Copy link
Contributor

meeber commented Aug 10, 2017

Makes sense. In a case like this one, I can understand accepting decreased precision in exchange for increased maintainability.

A couple of weeks ago I was thinking about the level of effort of making the chai-things plugin compatible with Chai v4. The current stance is we'd wait for #585 to be resolved before fixing chai-things, but that feels like a long ways away to me. Given that the plugin is basically unusable at the moment, I think it might be worth it to fix the plugin directly.

@hdzidic
Copy link

hdzidic commented Nov 29, 2017

I have the same issue - thanks for the workaround idea @Segev95

@keithamus
Copy link
Member

Hey @Segev95 thanks for the issue.

We've added this to our Roadmap https://github.com/chaijs/chai/projects/2! We'll be releasing chai 5 soon, but for now I'll close this issue because it is tracked on our roadmap.

@jessicabyrne
Copy link

@keithamus Is there a solution available through chai now?

@mirrorkeydev
Copy link

This isn't quite what OP was asking for, but in the spirit of contributing workarounds, here's what I came up with:

expect(arr.map((e) => e.id).sort()).to.deep.equal([1, 3, 6, 7]);

This requires you to test the validity of the entire array, but that happened to work for my use case. This could also be factored out into a helper function:

expect(extractProperty(arr, id)).to.deep.equal([1, 3, 6, 7]);

function extractProperty(arr, property) {
    return arr.map((e) => e.property).sort();
}

To be more in line with what OP is asking, I suppose you could also do something like:

expect(arr.map((e) => e['id']).includes( /* ID you're testing for */ )).to.be.true;

Which could be rewritten as:

expect(propertyValueInArray(arr, 'id', /* ID you're testing for */)).to.be.true;

function propertyValueInArray(arr, property, value) {
    return arr.map((e) => e[property]).includes(value);
}

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

No branches or pull requests

6 participants