-
Notifications
You must be signed in to change notification settings - Fork 468
Add strict check for dom
type
#367
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
Conversation
src/pretty-dom.js
Outdated
maxLength = getMaxLength(dom), | ||
options, | ||
) { | ||
if (!(dom instanceof HTMLDocument) && !(dom instanceof HTMLElement)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose the error is thrown at dom.outerHTML.length
which means Element
is sufficient. Otherwise we would also throw on svg elements.
Do we need to consider cross-realm instanceof checks here as well? Getting the window of an element would not work if we didn't get an Element in the first place. I think checking for typeof dom.outerHTML === 'string'
might be sufficient here in asserting that the given value implements Element
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose the error is thrown at
dom.outerHTML.length
which meansElement
is sufficient. Otherwise we would also throw on svg elements.
Unfortunately it isn't because document
isn't an instance of Element
I think checking for
typeof dom.outerHTML === 'string'
might be sufficient here in asserting that the given value implementsElement
.
I absolutely agree that typeof dom.outerHTML === 'string'
checking is enough however it may hide a real problem from a developer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately it isn't because document isn't an instance of Element
Which is why you would keep the HTMLDocument check.
Cross-realm problem still exists.
I absolutely agree that typeof dom.outerHTML === 'string' checking is enough however it may hide a real problem from a developer
That would be?
IMO runtime type checking is not necessary here. If people care about type checking then you already have very good solutions with flow or typescript.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Types may lies. Right now dom
typed as HTMLElement
However there is a test for rendering document
dom-testing-library/src/__tests__/pretty-dom.js
Lines 39 to 40 in a401bb5
test('prettyDOM supports receiving the document element', () => { | |
expect(prettyDOM(document)).toMatchInlineSnapshot(` |
Runtime checking isn't a silver bullet however it allows to fail fast when a library's user use it as not expected and teaches she how to do it right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Types may lies
Did it occur to you that it was a mistake instead of an intention to specify something wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, it did.
For me as a developer it's so cool to have strict contracts in a library. What do you think about an alternative conditional here like:
- if (!(dom instanceof HTMLDocument) && !(dom instanceof HTMLElement)) {
- throw new TypeError(
- 'Debuggable value should be an instance of HTMLDocument or HTMLElement.',
- )
- }
+ if (!('outerHTML' in dom)) {
+ throw new TypeError(
+ 'Debuggable object should have `outerHTML` field like an HTMLElement instance.',
+ )
+ }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds better but you're still using HTMLElement
which is too narrow. No need throw so many technicallaties around "Expected an element or document but got X".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for suggestion. I've updated this check and add a test
I didn't extend
Does it mean that I should write some tests for |
src/pretty-dom.js
Outdated
} | ||
if (!('outerHTML' in dom)) { | ||
const domType = typeof dom | ||
const domTypeName = domType === 'object' ? dom.constructor.name : domType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This branch is likely not covered. Also: This will throw on null
because typeof null === 'object'
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch. Thank you for explaining.
dom = getDocument().body, | ||
maxLength = getMaxLength(dom), | ||
options, | ||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inCypress
has failed with null
parameter so in addition I replaced arguments default initializations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me 👍
@all-contributors please add @mbelsky for code and tests |
I've put up a pull request to add @mbelsky! 🎉 |
🎉 This PR is included in version 6.6.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
Hey,
I face an issue and come with this pr :)
What:
Add strict check for
dom
'souterHTML
fieldWhy:
To improve DX.
As a new user I've called
debug(x)
wherex
was a result ofqueryAll*
. I've missed thatqueryAll*
returns an array and gotTypeError: Cannot read property 'length' of undefined
in my terminal.Checklist:
docs site N/A