diff options
-rw-r--r-- | .travis.yml | 14 | ||||
-rw-r--r-- | Gruntfile.js | 66 | ||||
-rw-r--r-- | package.json | 4 | ||||
-rw-r--r-- | test/data/testinit-jsdom.js | 14 | ||||
-rw-r--r-- | test/data/testinit.js | 11 | ||||
-rw-r--r-- | test/index.html | 12 | ||||
-rw-r--r-- | test/jquery.js | 64 | ||||
-rw-r--r-- | test/karma.context.html | 65 | ||||
-rw-r--r-- | test/karma.debug.html | 67 | ||||
-rw-r--r-- | test/unit/selector.js | 2 |
10 files changed, 188 insertions, 131 deletions
diff --git a/.travis.yml b/.travis.yml index 214a80978..114a9e9b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,20 @@ matrix: addons: chrome: stable firefox: latest + # Run ES module tests. + - node_js: "12" + env: + - NPM_SCRIPT="test:esmodules" + - BROWSERS="ChromeHeadless" + addons: + chrome: stable + # Run AMD tests. + - node_js: "12" + env: + - NPM_SCRIPT="test:amd" + - BROWSERS="ChromeHeadless" + addons: + chrome: stable # Run tests on Firefox ESR as well. - node_js: "12" env: diff --git a/Gruntfile.js b/Gruntfile.js index 351700743..2a6226a03 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -141,6 +141,14 @@ module.exports = function( grunt ) { ] } ], + client: { + qunit: { + + // We're running `QUnit.start()` ourselves via `loadTests()` + // in test/jquery.js + autostart: false + } + }, files: [ "test/data/jquery-1.9.1.js", "node_modules/sinon/pkg/sinon.js", @@ -150,32 +158,6 @@ module.exports = function( grunt ) { "test/jquery.js", - // Replacement for testinit.js#loadTests() - "test/data/testrunner.js", - "test/unit/basic.js", - "test/unit/core.js", - "test/unit/callbacks.js", - "test/unit/deferred.js", - "test/unit/deprecated.js", - "test/unit/support.js", - "test/unit/data.js", - "test/unit/queue.js", - "test/unit/attributes.js", - "test/unit/event.js", - "test/unit/selector.js", - "test/unit/traversing.js", - "test/unit/manipulation.js", - "test/unit/wrap.js", - "test/unit/css.js", - "test/unit/serialize.js", - "test/unit/ajax.js", - "test/unit/effects.js", - "test/unit/offset.js", - "test/unit/dimensions.js", - "test/unit/animation.js", - "test/unit/tween.js", - "test/unit/ready.js", - { pattern: "dist/jquery.*", included: false, served: true }, { pattern: "src/**", type: "module", included: false, served: true }, { pattern: "amd/**", included: false, served: true }, @@ -195,6 +177,36 @@ module.exports = function( grunt ) { main: { browsers: isTravis && travisBrowsers || [ "ChromeHeadless", "FirefoxHeadless" ] }, + esmodules: { + browsers: isTravis && travisBrowsers || [ "ChromeHeadless" ], + options: { + client: { + qunit: { + + // We're running `QUnit.start()` ourselves via `loadTests()` + // in test/jquery.js + autostart: false, + + esmodules: true + } + } + } + }, + amd: { + browsers: isTravis && travisBrowsers || [ "ChromeHeadless" ], + options: { + client: { + qunit: { + + // We're running `QUnit.start()` ourselves via `loadTests()` + // in test/jquery.js + autostart: false, + + amd: true + } + } + } + }, jsdom: { options: { @@ -206,7 +218,7 @@ module.exports = function( grunt ) { // choosing a version etc. for jsdom. "dist/jquery.js", - // Replacement for testinit.js#loadTests() + // A partial replacement for testinit.js#loadTests() "test/data/testrunner.js", // jsdom only runs basic tests diff --git a/package.json b/package.json index abfee2589..73789b2c2 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,9 @@ "start": "grunt watch", "test:browserless": "grunt && grunt test:slow", "test:browser": "grunt && grunt karma:main", - "test": "grunt && grunt test:slow && grunt karma:main", + "test:esmodules": "grunt && grunt karma:esmodules", + "test:amd": "grunt && grunt karma:amd", + "test": "grunt && grunt test:slow && grunt karma:main && grunt karma:esmodules && grunt karma:amd", "jenkins": "npm run test:browserless" }, "commitplease": { diff --git a/test/data/testinit-jsdom.js b/test/data/testinit-jsdom.js index 37e57d8c4..bdb3c178e 100644 --- a/test/data/testinit-jsdom.js +++ b/test/data/testinit-jsdom.js @@ -41,3 +41,17 @@ function url( value ) { return baseURL + value + ( /\?/.test( value ) ? "&" : "?" ) + new Date().getTime() + "" + parseInt( Math.random() * 100000, 10 ); } + +// The file-loading part of testinit.js#loadTests is handled by +// jsdom Karma config; here we just need to trigger relevant APIs. +this.loadTests = function() { + + // Delay the initialization until after all the files are loaded + // as in the JSDOM case we load them via Karma (see Gruntfile.js) + // instead of directly in testinit.js. + window.addEventListener( "load", function() { + window.__karma__.start(); + jQuery.noConflict(); + QUnit.start(); + } ); +}; diff --git a/test/data/testinit.js b/test/data/testinit.js index 4088e4671..61ffcbc8f 100644 --- a/test/data/testinit.js +++ b/test/data/testinit.js @@ -301,10 +301,11 @@ this.loadTests = function() { // QUnit.config is populated from QUnit.urlParams but only at the beginning // of the test run. We need to read both. - var amd = QUnit.config.amd || QUnit.urlParams.amd; + var esmodules = QUnit.config.esmodules || QUnit.urlParams.esmodules, + amd = QUnit.config.amd || QUnit.urlParams.amd; // Directly load tests that need evaluation before DOMContentLoaded. - if ( !amd || document.readyState === "loading" ) { + if ( ( !esmodules && !amd ) || document.readyState === "loading" ) { document.write( "<script src='" + parentUrl + "test/unit/ready.js'><\x2Fscript>" ); } else { QUnit.module( "ready", function() { @@ -360,7 +361,11 @@ this.loadTests = function() { } } else { - QUnit.load(); + if ( window.__karma__ && window.__karma__.start ) { + window.__karma__.start(); + } else { + QUnit.load(); + } /** * Run in noConflict mode diff --git a/test/index.html b/test/index.html index fff50faab..6260c49da 100644 --- a/test/index.html +++ b/test/index.html @@ -19,7 +19,7 @@ <!-- See testinit for the list of tests --> <script src="data/testinit.js"></script> - <!-- A script that includes jQuery min, dev, ES modules or AMD --> + <!-- A script that includes jQuery min, dev, ES modules or AMD modules --> <!-- Adds "basic" URL option, even to iframes --> <!-- iframes will not load AMD as loading needs to be synchronous for some tests --> <!-- Also executes the function above to load tests --> @@ -29,7 +29,15 @@ // Load tests if they have not been loaded // This is in a different script tag to ensure that // jQuery is on the page when the testrunner executes - if ( !QUnit.urlParams.esmodules && !QUnit.urlParams.amd ) { + // QUnit.config is populated from QUnit.urlParams but only at the beginning + // of the test run. We need to read both. + var esmodules = QUnit.config.esmodules || QUnit.urlParams.esmodules, + amd = QUnit.config.amd || QUnit.urlParams.amd; + + // Workaround: Remove call to `window.__karma__.loaded()` + // in favour of calling `window.__karma__.start()` from `loadTests()` + // because tests such as unit/ready.js should run after document ready. + if ( !esmodules && !amd ) { loadTests(); } </script> diff --git a/test/jquery.js b/test/jquery.js index c34c7c491..be2445395 100644 --- a/test/jquery.js +++ b/test/jquery.js @@ -8,36 +8,35 @@ parentUrl = activeScript && activeScript.src ? activeScript.src.replace( /[?#].*/, "" ) + FILEPATH.replace( /[^/]+/g, ".." ) + "/" : "../", - QUnit = window.QUnit || parent.QUnit, - require = window.require || parent.require, + QUnit = window.QUnit, + require = window.require, // Default to unminified jQuery for directly-opened iframes - urlParams = QUnit ? - QUnit.urlParams : + config = QUnit ? + + // QUnit.config is populated from QUnit.urlParams but only at the beginning + // of the test run. We need to read both. + { + esmodules: !!( QUnit.config.esmodules || QUnit.urlParams.esmodules ), + amd: !!( QUnit.config.amd || QUnit.urlParams.amd ) + } : + { dev: true }, - src = urlParams.dev ? + src = config.dev ? "dist/jquery.js" : "dist/jquery.min.js"; // Define configuration parameters controlling how jQuery is loaded if ( QUnit ) { - - // ES modules loading is asynchronous and incompatible with synchronous - // test loading in Karma. - if ( !window.__karma__ ) { - QUnit.config.urlConfig.push( { - id: "esmodules", - label: "Load as modules", - tooltip: "Load the jQuery module file (and its dependencies)" - } ); - QUnit.config.urlConfig.push( { - id: "amd", - label: "Load with AMD", - tooltip: "Load the AMD jQuery file (and its dependencies)" - } ); - } - QUnit.config.urlConfig.push( { + id: "esmodules", + label: "Load as modules", + tooltip: "Load the jQuery module file (and its dependencies)" + }, { + id: "amd", + label: "Load with AMD", + tooltip: "Load the AMD jQuery file (and its dependencies)" + }, { id: "dev", label: "Load unminified", tooltip: "Load the development (unminified) jQuery file" @@ -46,24 +45,29 @@ // Honor ES modules loading on the main window (detected by seeing QUnit on it). // This doesn't apply to iframes because they synchronously expect jQuery to be there. - if ( urlParams.esmodules && window.QUnit ) { + if ( config.esmodules && QUnit ) { // Support: IE 11+, Edge 12 - 18+ // IE/Edge don't support the dynamic import syntax so they'd crash // with a SyntaxError here. dynamicImportSource = "" + - "import( `${ parentUrl }src/jquery.js` ).then( ( { default: jQuery } ) => {\n" + - " window.jQuery = jQuery;\n" + - " if ( typeof loadTests === \"function\" ) {\n" + - " // Include tests if specified\n" + - " loadTests();\n" + - " }\n" + - "} );"; + "import( `${ parentUrl }src/jquery.js` )\n" + + " .then( ( { default: jQuery } ) => {\n" + + " window.jQuery = jQuery;\n" + + " if ( typeof loadTests === \"function\" ) {\n" + + " // Include tests if specified\n" + + " loadTests();\n" + + " }\n" + + " } )\n" + + " .catch( error => {\n" + + " console.error( error );\n" + + " QUnit.done();\n" + + " } );"; eval( dynamicImportSource ); // Apply similar treatment for AMD modules - } else if ( urlParams.amd && window.QUnit ) { + } else if ( config.amd && QUnit ) { require.config( { baseUrl: parentUrl } ); diff --git a/test/karma.context.html b/test/karma.context.html index e4f8a4f88..8439bef94 100644 --- a/test/karma.context.html +++ b/test/karma.context.html @@ -1,45 +1,44 @@ <!DOCTYPE html> <html lang="en" id="html"> <head> - <meta charset="utf-8"> - <title>CONTEXT</title> - <!-- Karma serves this page from /context.html. Other files are served from /base --> - <link rel="stylesheet" href="/base/test/data/testsuite.css" /> + <meta charset="utf-8"> + <title>CONTEXT</title> + <!-- Karma serves this page from /context.html. Other files are served from /base --> + <link rel="stylesheet" href="/base/test/data/testsuite.css" /> </head> <body id="body"> - <div id="qunit"></div> + <div id="qunit"></div> - <!-- Start: jQuery Test HTML --> - <!-- this iframe is outside the #qunit-fixture so it won't waste time by constantly reloading; the tests are "safe" and clean up after themselves --> - <iframe id="loadediframe" name="loadediframe" style="display:none;" src="/base/test/data/iframe.html"></iframe> - <div id="qunit-fixture"></div> - <!-- End: jQuery Test HTML --> + <!-- Start: jQuery Test HTML --> + <!-- this iframe is outside the #qunit-fixture so it won't waste time by constantly reloading; the tests are "safe" and clean up after themselves --> + <iframe id="loadediframe" name="loadediframe" style="display:none;" src="/base/test/data/iframe.html"></iframe> + <div id="qunit-fixture"></div> + <!-- End: jQuery Test HTML --> - <!-- Start: Karma boilerplate --> - <script src="/context.js"></script> - <script> - %CLIENT_CONFIG% - window.__karma__.setupContext(window); + <!-- Start: Karma boilerplate --> + <script src="/context.js"></script> + <script> + %CLIENT_CONFIG% + window.__karma__.setupContext(window); - %MAPPINGS% - </script> - %SCRIPTS% - <!-- End: Karma boilerplate --> + %MAPPINGS% + </script> + %SCRIPTS% + <!-- End: Karma boilerplate --> - <script src="/base/test/data/qunit-fixture.js"></script> - <script> - // Workaround: Remove call to window.__karma__.loaded() - // in favour of calling window.__karma__.start() at window.onload - // because tests such as unit/ready.js should run after document ready - window.addEventListener('load', function() { - window.__karma__.start(); + <script src="/base/test/data/qunit-fixture.js"></script> + <script> + // QUnit.config is populated from QUnit.urlParams but only at the beginning + // of the test run. We need to read both. + var esmodules = QUnit.config.esmodules || QUnit.urlParams.esmodules, + amd = QUnit.config.amd || QUnit.urlParams.amd; - // Workaround: https://github.com/karma-runner/karma-qunit/issues/92 - QUnit.testStart(function () { - // Restore content - document.getElementById("qunit-fixture").innerHTML = QUnit.config.fixture; - }); - }); - </script> + // Workaround: Remove call to `window.__karma__.loaded()` + // in favour of calling `window.__karma__.start()` from `loadTests()` + // because tests such as unit/ready.js should run after document ready. + if ( !esmodules && !amd ) { + loadTests(); + } + </script> </body> </html> diff --git a/test/karma.debug.html b/test/karma.debug.html index 9fdb4f641..2e1083c41 100644 --- a/test/karma.debug.html +++ b/test/karma.debug.html @@ -2,46 +2,45 @@ <html lang="en" id="html"> <head> %X_UA_COMPATIBLE% - <title>DEBUG</title> - <meta charset="utf-8"> - <!-- Karma serves this page from /context.html. Other files are served from /base --> - <link rel="stylesheet" href="/base/node_modules/qunit/qunit/qunit.css" /> - <link rel="stylesheet" href="/base/test/data/testsuite.css" /> + <title>DEBUG</title> + <meta charset="utf-8"> + <!-- Karma serves this page from /context.html. Other files are served from /base --> + <link rel="stylesheet" href="/base/node_modules/qunit/qunit/qunit.css" /> + <link rel="stylesheet" href="/base/test/data/testsuite.css" /> </head> <body id="body"> - <div id="qunit"></div> + <div id="qunit"></div> - <!-- Start: jQuery Test HTML --> - <!-- this iframe is outside the #qunit-fixture so it won't waste time by constantly reloading; the tests are "safe" and clean up after themselves --> - <iframe id="loadediframe" name="loadediframe" style="display:none;" src="/base/test/data/iframe.html"></iframe> - <div id="qunit-fixture"></div> - <!-- End: jQuery Test HTML --> + <!-- Start: jQuery Test HTML --> + <!-- this iframe is outside the #qunit-fixture so it won't waste time by constantly reloading; the tests are "safe" and clean up after themselves --> + <iframe id="loadediframe" name="loadediframe" style="display:none;" src="/base/test/data/iframe.html"></iframe> + <div id="qunit-fixture"></div> + <!-- End: jQuery Test HTML --> - <!-- Start: Karma boilerplate --> - <script src="/context.js"></script> - <script src="/debug.js"></script> - <script> - %CLIENT_CONFIG% + <!-- Start: Karma boilerplate --> + <script src="/context.js"></script> + <script src="/debug.js"></script> + <script> + %CLIENT_CONFIG% - %MAPPINGS% - </script> - %SCRIPTS% - <!-- End: Karma boilerplate --> + %MAPPINGS% + </script> + %SCRIPTS% + <!-- End: Karma boilerplate --> - <script src="/base/test/data/qunit-fixture.js"></script> - <script> - // Workaround: Remove call to window.__karma__.loaded() - // in favour of calling window.__karma__.start() at window.onload - // because tests such as unit/ready.js should run after document ready - window.addEventListener('load', function() { - window.__karma__.start(); + <script src="/base/test/data/qunit-fixture.js"></script> + <script> + // QUnit.config is populated from QUnit.urlParams but only at the beginning + // of the test run. We need to read both. + var esmodules = QUnit.config.esmodules || QUnit.urlParams.esmodules, + amd = QUnit.config.amd || QUnit.urlParams.amd; - // Workaround: https://github.com/karma-runner/karma-qunit/issues/92 - QUnit.testStart(function () { - // Restore content - document.getElementById("qunit-fixture").innerHTML = QUnit.config.fixture; - }); - }); - </script> + // Workaround: Remove call to `window.__karma__.loaded()` + // in favour of calling `window.__karma__.start()` from `loadTests()` + // because tests such as unit/ready.js should run after document ready. + if ( !esmodules && !amd ) { + loadTests(); + } + </script> </body> </html> diff --git a/test/unit/selector.js b/test/unit/selector.js index f5e15e8c2..a8204242a 100644 --- a/test/unit/selector.js +++ b/test/unit/selector.js @@ -1092,7 +1092,7 @@ QUnit.test( "pseudo - misc", function( assert ) { assert.t( "Multi-pseudo", "#ap:has(*), #ap:has(*)", [ "ap" ] ); assert.t( "Multi-pseudo with leading nonexistent id", "#nonexistent:has(*), #ap:has(*)", [ "ap" ] ); - assert.t( "Tokenization stressor", "a[class*=blog]:not(:has(*, :contains(!)), :contains(!)), br:contains(]), p:contains(]), :not(:empty):not(:parent)", [ "ap", "mark", "yahoo", "simon" ] ); + assert.t( "Tokenization stressor", "a[class*=blog]:not(:has(*, :contains(!)), :contains(!)), br:contains(]), p:contains(]):not(.qunit-source), :not(:empty):not(:parent):not(.qunit-source)", [ "ap", "mark", "yahoo", "simon" ] ); } else { assert.ok( "skip", ":has not supported in selector-native" ); assert.ok( "skip", ":has not supported in selector-native" ); |