-
Notifications
You must be signed in to change notification settings - Fork 20.6k
Build: Don't assume the browser environment; smoke test on Node w/ jsdom #1949
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
+26 bytes currently; perhaps that can be improved. EDIT: +35 bytes now. Final EDIT: the landed commit ended up at +32 bytes. |
@@ -11,7 +11,8 @@ jQuery.parseXML = function( data ) { | |||
|
|||
// Support: IE9 | |||
try { | |||
tmp = new DOMParser(); | |||
// jQuery.parseXML is browser-only | |||
tmp = new DOMParser(); // jshint ignore: line |
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.
DOMParser should just be added to globals.
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.
If we add DOMParser
to globals and use it somewhere on the top scope, we'll break Node & other environments that don't have it. That's why I went for explicitly marking places that are browser-only; I think it's safer (and there are only two such places on master
).
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 just don't like jshint comments. What about a jshintrc in the ajax folder?
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 don't like it either. :) But it seemed as a necessary evil.
We don't know if something in the ajax folder isn't run immediately when including jQuery. We know this about parseXML
and the xhr
transport but this seems dangerous to do globally for ajax.
I'm open for better suggestions; I just don't see them currently.
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.
How about creating a subdirectory src/ajax/var/browser-only/
with vars for DOMParser
& XMLHttpRequest
and put such a .jshintrc
with browser: true
there?
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.
Works for me.
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.
Done.
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.
@timmywil We could also use window.DOMParser
etc. which has the advantage that if jsdom ever gets support for that it starts to work.
In fact, jsdom
already supports XMLHttpRequest. I'll modify the PR.
Edit: done.
|
||
support.createHTMLDocument = (function() { | ||
var doc = document.implementation.createHTMLDocument( "" ); | ||
// Support: Node with jsdom<=1.5.0+ | ||
// jsdom's document created via the above method doesn't contain the body | ||
if (!doc.body) { |
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.
Spacing. Did jscs not pick this up?
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.
It didn't. :/
|
||
require( "jsdom" ).env( "", function (errors, window) { | ||
if (errors) { | ||
console.error(errors); |
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.
Spaces here too.
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 file might need to be added to the Gruntfile.
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.
Right; this is taken from my commit (e1303a3) at the standard-then-tests branch where the external file was actually necessary.
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.
BTW, when I inline it spawn
isn't even needed.
d6e7265
to
f91bc4a
Compare
"setTimeout": true, | ||
"clearTimeout": true, | ||
"setInterval": true, | ||
"clearInterval": true, |
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.
jsdom supports setTimeout
etc.; they wrap Node's setTimeout
but also cache results in order to auto-clear timeouts/intervals on window.close()
. This seems to be an extremely edge-case scenario and I envision we might want to support simpler than jsdom replacements for window
so it's better to use global setTimeout
.
Thoughts?
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.
@denis-sokolov claims it's a niche so I tend to agree. :)
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.
So it seems safe to just use setTimeout
and the others global then? if node and browsers both support it global I think it should be safe.
|
||
support.createHTMLDocument = (function() { | ||
var doc = document.implementation.createHTMLDocument( "" ); | ||
// Support: Node with jsdom<=1.5.0+ | ||
// jsdom's document created via the above method doesn't contain the body |
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.
Wow, didn't we pull out something similar for framed docs? There are no new bugs it seems.
// Short list as a high frequency watch task | ||
grunt.registerTask( "dev", [ "build:*:*", "lint" ] ); | ||
|
||
// Default grunt | ||
grunt.registerTask( "default", [ "jsonlint", "dev", "uglify", "dist:*", "compare_size" ] ); | ||
grunt.registerTask( "default", | ||
[ "jsonlint", "dev", "uglify", "dist:*", "compare_size", "node-smoke-test" ] ); |
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.
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.
better still, moving "node-smoke-test" into a "test" task.
I had this in one version of a patch but this would be the only thing in the test
task so far.
We'll also need to change the npm test
script to do grunt test
instead of just grunt
.
Is that what you want?
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.
Yes.
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.
We'll need to update Jenkins jobs to use npm test
instead of grunt
what they do now. I'll do it.
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.
Done & done.
I like it. 👍 |
30b61b5
to
3143efc
Compare
// Short list as a high frequency watch task | ||
grunt.registerTask( "dev", [ "build:*:*", "lint" ] ); | ||
|
||
// Default grunt | ||
grunt.registerTask( "test", [ "default", "node-smoke-test" ] ); |
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.
Shouldn't that go the other way (default
including test
)?
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.
Ah, that's what you meant.
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.
So, just to be sure:
grunt.registerTask( "test", [ "node-smoke-test" ] );
grunt.registerTask( "default", [ "jsonlint", "dev", "uglify", "dist:*", "test", "compare_size" ] );
That will mean that compare_size
won't run if test
fails. Is that OK?
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'm fine with it, not least of all because it's consistent with Sizzle. And if that changes in the future, it should change everywhere.
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 was thinking about it but I'm not convinced that's the best approach. In Core grunt
is so far linting and building the project and that's it. Current smoke-testing is short but we'll be adding Promises/A+ compliance test (see e1303a3) which is not quick so I doubt we want to auto-run it just when we just want to build the files.
We can run Node smoke-testing in the default
task as it's quick but putting it in the test
task will IMO mean we'll need to refactor it again in the nearby future.
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 trust your opinion more than mine here :)
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.
Do we really need to add new task to default
task? Those tests are for jsdom compliance, do we really need every time we want to build it?
We need to run grunt testswarm on Jenkins explicitly as it needs parameters, see config of this job:
Don't have access to it, you mean something like this -
grunt testswarm:d6c97abb744bfe8c67ab9158aecdb5bb1c05e47b:/usr/local/bin/tools/node-testswarm-config.json:jquery:jquery
?
We could you use new npm feature - passing arguments to npm scripts, although it doesn't look pretty.
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.
Do we really need to add new task to default task? Those tests are for jsdom compliance, do we really need every time we want to build it?
They're rather fast, though (500 ms on my machine) and they prevent us from accidentally commiting code breaking compat with Node. We do run linters on each grunt
run for example.
On the other hand, the jsHint setup when changed like in this PR will catch most Node incompatibilities so maybe it's not so important to check it all the time.
I'll go by the following solution:
npm run build # does npm install && grunt
npm test # does grunt test
grunt testswarm:sthsthsth
I'll land this now without running Node smoke tests on grunt
; we can revisit later. I want this on master
ASAP, though so that we're covered agains past mistakes from now on.
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'd be in favor of running the tests all the time, but that's just me.
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.
@jaubourg They require jsdom
presence, though and some people may have a problem with that (see my comment: #1949 (comment)). I'm not sure if we have a perfect solution here without optionalDevDependencies
but that's just one thing to consider.
I was made aware by email that:
So it seems we shouldn't just flat out fail if jsdom fails to install as it's not required by the build process. I'd normally just put it in The only way to resolve it that I see is to create an Any better ideas? EDIT: I still want to land this PR even if we don't figure out how to solve the presented problem soon; we can figure it out later but it still seems important. |
Landed. I went for running the tests via:
In this was we can run tests in the same way on
@jaubourg |
I've looked a little at jsdom build requirements and they'll all be gone once Node 0.12 comes out (which, cough, should be soon): jsdom/jsdom#683 (comment) Judging by how complicated and fragile any workaround would be here and considering that the problem will disappear in some time I'd rather leave it as is. |
Fixes jquerygh-2501 Closes jquerygh-2504 Refs jquerygh-1950 Refs jquerygh-1949 Refs jquerygh-2397 Refs jquerygh-1537 Refs 842958e
Fixes jquerygh-2133 Fixes jquerygh-2501 Closes jquerygh-2504 Refs jquerygh-1950 Refs jquerygh-1949 Refs jquerygh-2397 Refs jquerygh-1537 Refs 842958e
Fixes jquerygh-2133 Fixes jquerygh-2501 Closes jquerygh-2504 Refs jquerygh-1950 Refs jquerygh-1949 Refs jquerygh-2397 Refs jquerygh-1537 Refs jquerygh-2504 Refs 842958e
Fixes jquerygh-2133 Fixes jquerygh-2501 Closes jquerygh-2504 Refs jquerygh-1950 Refs jquerygh-1949 Refs jquerygh-2397 Refs jquerygh-1537 Refs jquerygh-2504 Refs 842958e
Fixes gh-1950