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

refactor: utils.type() #4306

Closed
boneskull opened this issue May 28, 2020 · 1 comment · Fixed by #4457
Closed

refactor: utils.type() #4306

boneskull opened this issue May 28, 2020 · 1 comment · Fixed by #4457
Labels
status: accepting prs Mocha can use your help with this one! type: chore generally involving deps, tooling, configuration, etc.

Comments

@boneskull
Copy link
Contributor

utils.type(value) is a function which returns a human-readable "type" of whatever value you pass it.

About type():

  • It works by first comparing against a set of tricky values (undefined, null, etc); if it does not find these, it then looks at the result of Object.prototype.toString.call(value) (e.g., [Object object]) and extracting the second token from within the brackets
  • It's pretty useful, as we get things like date for type(new Date()) and error for type(new Error()); more granularity than typeof offers
  • Originally, this was used for object comparison--specifically, displaying diffs
  • Over time, we (I?) started using it elsewhere, because of the convenience it offers: a single function to determine the type of a given value, instead of several different methods, which invariably turn into sprawling if/else-if/else statements:
    • Array.isArray(value) for arrays (where available)
    • value === null for null
    • typeof value for most other stuff

With additions of async functions and ESM, the Object.prototype.toString strategy adds new potential return values of type():

  • type(async function() {}) returns asyncfunction
  • given module n imported via let n = await import(name), type(n) returns module

While the new values may be good for displaying diffs, they are not helpful in the general case. For example, a return value of asyncfunction will tell us that value is a function which returns a Promise, but a function needn't be async to return a Promise, so it adds little value. We have no known use case for a return value of module outside of diffing (and maybe not even then--we should probably play with that one in our test suite).

This is what I'd like to propose:

  • type() should be renamed to e.g., canonicalType()
  • its use should be limited to utils.canoncalize(), which is part of the comparison/diff code
    • we may want to actually pull the diffing-related functions into its own module, just for sake of organization. utils is just a code dump, as you'd expect.
  • a new function (type()?) should be created to be used elsewhere in the codebase
  • the new function should either be:
    • a custom implementation tailored the various use-cases around the codebase, or
    • a thin wrapper around a third-party type-checking library
  • usages of typeof, Array.isArray(), around the codebase should be replaced with this new function, for consistency

Happy to hear alternatives, as long as those alternatives do not involve "rewrite Mocha in TypeScript" :trollface:

@boneskull boneskull added status: accepting prs Mocha can use your help with this one! type: chore generally involving deps, tooling, configuration, etc. labels May 28, 2020
@ghost
Copy link

ghost commented Aug 6, 2020

Hi @boneskull I can look into this.

@boneskull boneskull linked a pull request Oct 9, 2020 that will close this issue
boneskull pushed a commit that referenced this issue Oct 9, 2020
* Split utils.type() into canonicalType() for diffs and type() for everything else

* Change function to be much more generic and replace all the existing calls with the new name

* Make utils.type straightforward and change nodejs serializer calls to it

* Refactor utils.type() and related code to use modern ES
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: accepting prs Mocha can use your help with this one! type: chore generally involving deps, tooling, configuration, etc.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant