question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

This issue facilitates discussions about matchers design

Problem of having multiple ways to match the same thing

toEqual is quite a beast and thus many matchers can be implemented just by using it:

1)
expect(true).toEqual(true)
// instead of
expect(true).toBeTrue()

// same goes for other primitive values like (false/null/undefined)

2)
expect("abc").toEqual(any(String))
//instead of
expect("abc").toBeInstanceOf(String)

I had this problem on my mind for some time already and I initially thought that avoiding this duplication entirely is a good thing but I believe that having some level of consistency with chai can beneficial. For example, I think 1) is fine (it’s clear and shorter 🤔)

Any thoughts on this one?

Essentials matchers to implement in the first batch

Asymmetric:

  • any (or anyInstanceOf? much longer, much more explicit… i need to admit that any was confusing for me when I first saw it)
  • anyString / anyStringMatching / anyStringContaining
  • anyNumber

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
sz-piotrcommented, May 10, 2020

Regarding multiple ways of doing the same thing.

I consider this an antipattern leading to unnecessary headaches. It forces the programmer to make more decisions that he actually needs. It also requires him to visit the documentation to see if maybe there is something actually different between the options. It also makes the library author have to pick a version for each example, leading to additional overhead and making documentation less straightforward.

Regarding essential matchers.

I am a big fan of appropriate and concise naming. Therefore I would prefer overloading some matchers to make it easier to reason.

  • .toThrow('message')
  • .toThrow(/message/)
  • .toThrow(ErrorClass)
  • .toThrow(ErrorClass, 'message')
  • .toThrow(ErrorClass, /message/)
  • .toBeA(MyClass) - uses instanceof
  • .toBeA('string') - uses typeof

Knowing this it is easier to resolve the assymetric ones. Just make it consistent with symmetric.

  • expect.anything()
  • expext.a(MyClass)
  • expect.a('string')
1reaction
sz-piotrcommented, May 10, 2020

@krzkaczor do here is how I see it. There are two operators in JS. typeof and instanceOf. One is used for primitives like string or number and always returns 'object' for other values (sadly including null). The other is used for class instances like Error and returns false for strings and numbers.

What we want to do is combine those two operators under the name of a. I propose to use one if you pass a string the other if you pass a class. You want only to support only classes (and weird things like String which are almost classes).

If we go your route which is quite nice in its simplicity we run into the following problems.

  • how to check for null and undefined (maybe the solution is to never match them)
  • all primitives require custom code and introduction of new ones can be problematic (see BigInt), because you might not be able to match them
  • we loose the simple mental model of using typeof and instanceof

Despite those problems the more I think about it the more I am convinced it is the way to go. Also if it does not use typeof or instanceof directly it is ok to use stuff like Array.isArray() under the hood

Read more comments on GitHub >

github_iconTop Results From Across the Web

PHP RFC: Match expression v2
This RFC proposes adding a new match expression that is similar to switch but with safer semantics and the ability to return values....
Read more >
RFC 4647: Matching of Language Tags
RFC 4647 Matching of Language Tags September 2006 Table of Contents 1. ... The character '*' is a "wildcard" that matches any sequence...
Read more >
2005-match-ergonomics - The Rust RFC Book
Rather than using auto-deref and auto-referencing, this RFC introduces default binding modes used when a reference value is matched by a non-reference pattern....
Read more >
RFC: Matchers · Issue #7 · dethcrypto/earl · GitHub
This issue facilitates discussions about matchers design Problem of having multiple ways to match the same thing toEqual is quite a beast and...
Read more >
North Shore RFC · Match Reports & Videos
North Shore Rugby Football Club competes in the men's Division II of the New England Rugby Football Union.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found