Skip to content

Commit

Permalink
Merge 8e6a368 into 4b2ca29
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavnikolaj committed Sep 8, 2020
2 parents 4b2ca29 + 8e6a368 commit 068b5bc
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 8 deletions.
31 changes: 31 additions & 0 deletions documentation/assertions/array-like/to-contain.md
Expand Up @@ -46,3 +46,34 @@ not to contain { name: 'Jane Doe' }
{ name: 'Jane Doe' } // should be removed
]
```

You can use the `only` flag to indicate that you want no other items to
be in the subject.

```js
expect(
[{ name: 'John Doe' }, { name: 'Jane Doe' }],
'to only contain',
{ name: 'Jane Doe' },
{ name: 'John Doe' }
);
```

In case there are more items than that in your subject, you will get the
following output:

```js
expect([{ name: 'Jane Doe' }, { name: 'John Doe' }], 'to only contain', {
name: 'Jane Doe',
});
```

```output
expected [ { name: 'Jane Doe' }, { name: 'John Doe' } ]
to only contain { name: 'Jane Doe' }
[
{ name: 'Jane Doe' },
{ name: 'John Doe' } // should be removed
]
```
34 changes: 28 additions & 6 deletions lib/assertions.js
Expand Up @@ -766,11 +766,19 @@ module.exports = (expect) => {
);
});

expect.addAssertion('<array-like> [not] to contain <any+>', function (
expect.addAssertion('<array-like> [not] to [only] contain <any+>', function (
expect,
subject
) {
const args = Array.prototype.slice.call(arguments, 2);

if (expect.flags.only && expect.flags.not) {
expect.errorMode = 'bubble';
expect.fail(
'The "not" flag cannot be used together with "to only contain".'
);
}

expect.withError(
() => {
args.forEach((arg) => {
Expand All @@ -782,19 +790,33 @@ module.exports = (expect) => {
'[not] to be truthy'
);
});
if (expect.flags.only) {
expect(subject.length, 'to be', args.length);
}
},
(e) => {
expect.fail({
diff:
expect.flags.not &&
((output, diff, inspect, equal) =>
diff(
diff(output, diff, inspect, equal) {
if (expect.flags.not) {
return diff(
subject,
Array.prototype.filter.call(
subject,
(item) => !args.some((arg) => equal(item, arg))
)
)),
);
} else if (expect.flags.only) {
var excessItems = Array.prototype.filter.call(subject, (item) =>
args.some((arg) => equal(item, arg))
);
var missingItems = Array.prototype.filter.call(
args,
(arg) => !subject.some((item) => equal(arg, item))
);

return diff(subject, excessItems.concat(missingItems));
}
},
});
}
);
Expand Down
64 changes: 62 additions & 2 deletions test/assertions/to-contain.spec.js
Expand Up @@ -32,7 +32,7 @@ describe('to contain assertion', () => {
' The assertion does not have a matching signature for:\n' +
' <null> not to contain <string>\n' +
' did you mean:\n' +
' <array-like> [not] to contain <any+>\n' +
' <array-like> [not] to [only] contain <any+>\n' +
' <string> [not] to contain <string+>'
);

Expand Down Expand Up @@ -80,7 +80,7 @@ describe('to contain assertion', () => {
' The assertion does not have a matching signature for:\n' +
' <number> to contain <number>\n' +
' did you mean:\n' +
' <array-like> [not] to contain <any+>\n' +
' <array-like> [not] to [only] contain <any+>\n' +
' <string> [not] to contain <string+>'
);
});
Expand Down Expand Up @@ -166,6 +166,66 @@ describe('to contain assertion', () => {
});
});

describe('with the only flag', () => {
it('should not throw when all items are included in the subject', () => {
expect(function () {
expect(
[{ bar: 456 }, { foo: 123 }],
'to only contain',
{ foo: 123 },
{ bar: 456 }
);
}, 'not to throw');
});

it('should throw when all items are not included in the subject', () => {
expect(
function () {
expect([{ bar: 456 }], 'to only contain', { foo: 123 }, { bar: 456 });
},
'to throw exception',
'expected [ { bar: 456 } ] to only contain { foo: 123 }, { bar: 456 }\n' +
'\n' +
'[\n' +
' { bar: 456 }\n' +
' // missing { foo: 123 }\n' +
']'
);
});

it('should throw when all items are included in the subject but subject has other items as well', () => {
expect(
function () {
expect(
[{ bar: 456 }, { foo: 123 }, { baz: 789 }],
'to only contain',
{ foo: 123 },
{ bar: 456 }
);
},
'to throw exception',
'expected [ { bar: 456 }, { foo: 123 }, { baz: 789 } ]\n' +
'to only contain { foo: 123 }, { bar: 456 }\n' +
'\n' +
'[\n' +
' { bar: 456 },\n' +
' { foo: 123 },\n' +
' { baz: 789 } // should be removed\n' +
']'
);
});

it('should throw when combining the not and only flags', () => {
expect(
function () {
expect([{ foo: 123 }], 'not to only contain', { foo: 123 });
},
'to throw exception',
'The "not" flag cannot be used together with "to only contain".'
);
});
});

it('should not highlight overlapping partial matches', () => {
expect(
function () {
Expand Down

0 comments on commit 068b5bc

Please sign in to comment.