mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Build: Make Karma work in ES modules mode
Also, run such a suite in CI to make sure modules are working as expected when used directly. Closes gh-4550
This commit is contained in:
parent
f37c2e51f3
commit
341c6d1b5a
14
.travis.yml
14
.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:
|
||||
|
66
Gruntfile.js
66
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
|
||||
|
@ -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": {
|
||||
|
@ -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();
|
||||
} );
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
64
test/jquery.js
vendored
64
test/jquery.js
vendored
@ -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
|
||||
} );
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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" );
|
||||
|
Loading…
Reference in New Issue
Block a user