groupon/assertive

Support collection meta-assertions

jkrems opened this issue · 3 comments

Brought up in #11

  • assert.every: check should pass for all elements
  • assert.some: check should pass for at least one element
  • assert.notAll: check should fail for at least one element (inverse of every)
  • assert.none: check should fail for all elements (inverse of some)
Additional notes:
  • Empty collections always fail
  • Both objects and arrays should be supported; if we want to be fancy also Set and Map
  • Custom checks should be supported

Open question: what is the signature of a check? Proposal: truthy or equality with true is pass, everything else (including throwing) is fail. The function arguments could be either just the element or the complete [].every tupel of (element, index, collection). The latter would make it harder to integrate with the built-in assertions which are very particular about their arguments; on the other hand having access to the index in custom checks might have advantages.

Examples:
assert.every [ 0, 3, 6 ], (n) -> n % 3 == 0
assert.every [ 0, 3, 6 ], assert.truthy

# var args? argument order?
some include, "a", [ "foo", "bar", "zapp" ]
some [ "foo", "bar", "zapp" ], include, "a"

While I understand how you think, I'd say that none and every are (polar) opposites (same for some and notAll), though the pairings you list are more conceptual inverses. Irrelevant hair splitting; the feature idea is great. :-)

Good call on empty collection = failure. I'd like the failure messages to note this state of things explicitly, besides a user-passed failure description. Also worth some testing and play is figuring out in greater detail what amounts to the most useful failure messages. We might want to start light, as these tests quite likely will/could produce huge amounts of data, even if we convey just a fraction and each assertion short-circuits as soon as it can, as it should.