unexpected icon indicating copy to clipboard operation
unexpected copied to clipboard

Better output from `to have properties`

Open msiebuhr opened this issue 9 years ago • 3 comments

> var expect = require('unexpected');
> expect({a:1, b:2}, 'to have properties', ['a', 'b', 'c'])
UnexpectedError:
expected { a: 1, b: 2 } to have properties [ 'a', 'b', 'c' ]

This gets rather pointless when the tested object has more than a few dozen properties. And it doesn't tell you if it considers the required properties as strict set equality or a subset.

To get around this, I've re-purposed the code from https://github.com/unexpectedjs/unexpected/issues/255#issuecomment-230700611 to this bastard-thing:

> expect(Object.keys({a:1, b:2}), 'to be a subset of', ['b', 'c']);
expected [ 'a', 'b' ] to be a subset of [ 'b', 'c' ]
[
  'a', // should be removed
  'b'
]

(Yes, I know the assertion isn't the same, but it illustrates the difference in output quite well.)

msiebuhr avatar Jul 07 '16 08:07 msiebuhr

Hi Morten, cool to get an issue from you :-)

The assertion you are suggesting have a different semantics than to have properties that will just check that the specified properties are present. The assertion you are making - if I understand it correctly - is asserting that there most not be any keys outside a recognized set. Which might be useful. I stopped to have properties when to satisfy was introduced. If I need to check the presence for a set of keys I use to have keys. But that does not mean we should make the output of to have properties as good a possible. So let's discuss that.

I would like the output to state the keys I'm missing when the assertion fails for both to have keys and to have properties. Something like:

expect({a:1, b:2}, 'to have properties', ['a', 'b', 'c'])

output:

expected { a: 1, b: 2 } to have properties [ 'a', 'b', 'c' ]
  property c is missing

sunesimonsen avatar Jul 09 '16 21:07 sunesimonsen

Hep!

I'm not arguing for a new assertion here; I'm merely using it illustrate that the error message of to have properties isn't terribly informative on objects w. ~20+ properties. You suggestion seem quite reasonable to me.

I mostly implemented it as a diff as I could see multiple errors in one pass;

expect({a:1, b:2, x:3}, 'to only have keys', ['a', 'b', 'c', 'd']);

Should ideally give

expected {a:1, b:2, x:3} to have keys ['a', 'b', 'c', 'd']
  Key 'c' is missing
  Key 'd' is missing
  Key 'x' should not be there

(Also, hadn't noticed to have keys. I just went straight for to have properties...)

msiebuhr avatar Jul 11 '16 08:07 msiebuhr

Yes exactly, but maybe a bit more compact:

expected {a:1, b:2, x:3} to only have keys ['a', 'b', 'c', 'd']
  keys c, d is missing
  key x should be removed

sunesimonsen avatar Jul 11 '16 09:07 sunesimonsen