-
Notifications
You must be signed in to change notification settings - Fork 20.6k
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
Tests: Add support for running unit test via Grunt with Karma #3744
Conversation
@Krinkle, thanks for your PR! By analyzing the history of the files in this pull request, we identified @timmywil, @CDAGaming and @all3fox to be potential reviewers. |
The tests are passing to show that the basic infrastructure works, but the majority of Ajax tests has not been ported yet (passing because I commented them out). There are also a number of tests outside Looking for further feedback before I port the rest. |
package.json
Outdated
"load-grunt-tasks": "3.5.2", | ||
"native-promise-only": "0.8.1", | ||
"promises-aplus-tests": "2.1.2", | ||
"q": "1.5.0", | ||
"qunit-assert-step": "1.1.1", | ||
"qunitjs": "2.4.0", | ||
"qunitjs": "1.23.1", |
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.
Why did you have to downgrade?
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.
@mgol The previous upgrades were fake. We are still on QUnit 1.20, see external
and note how the previous "updates" did not run npmcopy to update that file. Contrary to index.html, Karma does actually include qunitjs from node_modules directly and our tests don't actually support 2.x yet right now. This commit actually "upgrades" qunitjs from 1.20 to 1.23, although I haven't yet committed the updated external copy for the non-Karma test.
I'll do that in a separate commit before this one.
This is awesome, @Krinkle. 👏 I think it's fine that Karma tests don't run AJAX tests for the time being, it still helps in the majority We should strive to reduce duplication, though, in the current state of the PR a lot of HTML fixtures are repeated in various files. |
test/middleware-mockserver.js
Outdated
resp.end( req.query.response ); | ||
}, | ||
"test/data/ajax/evalScript.php": function( req, resp, next ) { | ||
resp.writeHead( 200 ); |
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.
Are most of those mocks identical just because they haven't been ported yet?
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.
Indeed. This is just a copy-paste stub.
@mgol Regarding fixture duplication, I agree. I'll try and generate these automatically in some way with a precommit/pretest Grunt task perhaps. I'd actually much prefer to move it to a separate file (e.g. The main reason this isn't viable at the moment is because of traversal tests depending on I'll get rid of that as well, in a separate commit before this one. |
The previous QUnit updates since b97c8d3 were ineffective as they only updated package.json (and unused files in node_modules), but did not run 'grunt npmcopy' or commit the actually used files in external/. Move the version back from 2.4.0 to 1.23.1 and actually run npmcopy. An update to 2.x should happen at some point, but let's first go to a newer 1.x version that fixes minor bugs for jquerygh-3744, without requiring any updates to the tests. Also revert ineffective updates to qunit-assert-step back to the version actually in use.
This non-standard wrapper around #qunit-fixture makes the tests needlessly complicated to run. This is needed for jquery#3744, so that we can easily run the tests from another entry point.
In preparation for jquery#3744, so that we can easily reuse the fixture from multiple entry points (e.g. test/index.html, Karma context, and Karma debug). Setting QUnit.config.fixture is a QUnit 2.x fixture, so for now also set it back into the element at run-time.
89b90fd
to
1022b43
Compare
* Add 'grunt karma:main' task that runs tests via Karma. - Karma uses its own server and uses its own HTML page by default. All files to be served are registered, and for the most part also loaded ("included") through Karma. - Use the 'customContextFile' option, because: * Preserve the qunit-fixture we have. * Workaround karma-qunit bug. - Use the 'customDebugFile' option, because (above reasons) and: * Create 'qunit' element and load QUnit CSS styles for easier debugging. * Move definition of 'isSwarm' and 'basicTests' out of loadTests(), given Karma will run without that function. * In addition to all the above, start porting some of the PHP mocks to Node.js. (The Ajax tests currently assume being served from Apache with mod_php.). I originally planned on addressing this by starting another Node server before Karma starts, somehow injecting its url, and stopping it after Karma. Instead, let's try to use Karma's support for middleware to (hopefully) make this prettier. Ref issue jquerygh-1999, pull jquerygh-3744.
@mgol Up and ready for further review. |
I may not have time to review this further before somewhere next week.
|
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 PR is great; thanks so much!
Could you also replace use of 404.txt, 404.html, and someFileThatDoesNotExist.html in test/unit/ajax.js so the console isn't polluted with irrelevant warnings?
<!DOCTYPE html> | ||
<html lang="en" id="html"> | ||
<head> | ||
%X_UA_COMPATIBLE% |
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.
What is the purpose of this? It doesn't appear in karma.context.html.
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's there by default in Karma's debugContextFile, which this file is a derivative of. I don't why don't have it in their non-debug file by default.
<script src="/context.js"></script> | ||
<script src="/debug.js"></script> | ||
<script> | ||
%CLIENT_CONFIG% |
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.
And this is missing window.__karma__.setupContext(window)
... it would be great to unify these two files, but I don't see anything in Karma that allows a "debug" signal through (e.g., an %IS_DEBUG%
directive).
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.
Update: though we could use a kludgy test like /^[/]debug\b/.test( location.pathname )
.
"test/unit/tween.js", | ||
"test/unit/ready.js", | ||
|
||
{ pattern: "dist/jquery.js", included: false, served: 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.
How do we actually take advantage of this to test unminified code?
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.
That'll be a future improvement, but the way it would work is basically you create another karma task, one like the current one that includes dist/jquery.min.js
in files
and one that includes dist/jquery.js
instead.
I had to whiltelist the file even in the current Grunt karma task because one of the iframes we load in the tests load test/jquery.js
, which then loads dist/jquery.js
in some cases.
test/data/mock.php
Outdated
@@ -0,0 +1,241 @@ | |||
<?php | |||
class MockServer { |
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.
👏 👏
|
||
public function respond( stdClass $req ) { | ||
if ( !isset( $req->query['action'] ) || !method_exists( $this, $req->query['action'] ) ) { | ||
header( "HTTP/1.0 400 Bad Request" ); |
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.
TIL more about PHP than I ever wanted to.
test/data/mock.php
Outdated
public function respond( stdClass $req ) { | ||
if ( !isset( $req->query['action'] ) || !method_exists( $this, $req->query['action'] ) ) { | ||
header( "HTTP/1.0 400 Bad Request" ); | ||
echo "Invalid action query."; |
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.
A nit, but can you make sure to include trailing newlines in content bodies?
$this->cspFile = __DIR__ . '/support/csp.log'; | ||
} | ||
|
||
public function respond( stdClass $req ) { |
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.
TODO: write a generic handler covering 80% of cases by responding to requests that specify delay, headers, and content body, e.g.
?wait=1&header=Content-Type:text/plain&content=foo%0Abar
or
?header=Content-Security-Policy:default-src+'self';+report-uri+./mock.php?action=cspLog&header=Content-Type:text/html&contentFile=csp.include.html
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've already narrowed down the number of different response handlers from what it originally was. Any additional improvements can be done later instead of blocking this pull.
I do not, however, that we don't currently have cases where we need multiple of wait
, header
and content
. Indicated by there not being any such method right now that does multiple. It's pretty well-isolated. Making it more generic and changing the actual fixtures used would be better, but that also requires more careful examination of what the tests are actually testing and what they need. For example, some tests probably don't need the exact output they get right now.
test/middleware-mockserver.js
Outdated
var getRawBody = require( "raw-body" ); | ||
|
||
var cspLog = ""; | ||
var mocks = { |
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 and mock.php should cross-reference each other to minimize divergence.
I'm sorry, it seems I won't have enough time to review this properly. Once @gibson042 approves the PR it's fine for me to land and we can improve on that in future PRs. |
@Krinkle did you just fix the QUnit |
Thanks, I'll address the issues raised by @gibson042. @mgol Commit 6b5debe only fixes the state of qunitjs for npmcopy. Running |
The previous QUnit updates since b97c8d3 were ineffective as they only updated package.json (and unused files in node_modules), but did not run 'grunt npmcopy' or commit the actually used files in external/. Move the version back from 2.4.0 to 1.23.1 and actually run npmcopy. An update to 2.x should happen at some point, but let's first go to a newer 1.x version that fixes minor bugs for jquerygh-3744, without requiring any updates to the tests. Also revert ineffective updates to qunit-assert-step back to the version actually in use.
This non-standard wrapper around #qunit-fixture makes the tests needlessly complicated to run. This is needed for jquery#3744, so that we can easily run the tests from another entry point.
Only used by 1 test (unit/offset.js), move it to there instead.
In preparation for jquery#3744, so that we can easily reuse the fixture from multiple entry points (e.g. test/index.html, Karma context, and Karma debug). Setting QUnit.config.fixture is a QUnit 2.x fixture, so for now also set it back into the element at run-time.
Various urls were missing this prefix, either explicitly or via url(). This commit fixes the odd ones that were missing the prefix, which was causing some tests to fail under Karma runner, where the base is different because tests are served from root (/), but files are served from /base (e.g. /base/test/data). Also, to avoid regressing this in the future, change baseURI to be the path to /test/data instead of the path to /test so that it doesn't silently make tests without it pass when run from /test/index.html.
* Add 'grunt karma:main' task that runs tests via Karma. - Karma uses its own server and uses its own HTML page by default. All files to be served are registered, and for the most part also loaded ("included") through Karma. - Use the 'customContextFile' option, because: * Preserve the qunit-fixture we have. * Workaround karma-qunit bug. - Use the 'customDebugFile' option, because (above reasons) and: * Create 'qunit' element and load QUnit CSS styles for easier debugging. * Move definition of 'isSwarm' and 'basicTests' out of loadTests(), given Karma will run without that function. * In addition to all the above, start porting some of the PHP mocks to Node.js. (The Ajax tests currently assume being served from Apache with mod_php.). I originally planned on addressing this by starting another Node server before Karma starts, somehow injecting its url, and stopping it after Karma. Instead, let's try to use Karma's support for middleware to (hopefully) make this prettier. Ref issue jquerygh-1999, pull jquerygh-3744.
* Merge all PHP stubs into one MockServer class. * Complete the middleware-mockserver.js port (Node.js equivalent). Notes: * Merge action=script, and action=evalScript. (Similar) * Merge action=wait, action=longLoadScript, action=dont_return. (Similar) * Merge action=status, and action=nocontent. (Similar) * Renamed text.php to text.txt. (No PHP code) * Merge references to 404.php, 404.html, and someFileThatDoesNotExist.html to 404.txt, and add a handler for the latter to test middleware to avoid warnings in the Karma server output. * Remove data/test.php. (Unused) Now that all tests pass, also add 'grunt karma:main' to npm test (for use in local development and on Travis CI). Also add a separate 'npm run jenkins' for use on jenkins.jquery.com where we won't run Chrome (runs TestSwarm instead). Fixes jquery#1999.
@gibson042 Fix ups:
|
@Krinkle @timmywil AJAX tests fail after this PR has been merged: http://swarm.jquery.org/job/6563. |
For me commands
|
Same for me. @Krinkle, is that a leftover config? |
They're not leftover, but I'll look into why they aren't working. Let's continue the conversation at #3922. |
Summary
grunt karma:main
task that runs tests via Karma.grunt karma:main
tonpm test
by default.Checklist
Fixes #1999.