]> source.dussan.org Git - jquery.git/commitdiff
Build: Make Karma work in AMD mode
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>
Tue, 21 Jan 2020 12:26:47 +0000 (13:26 +0100)
committerGitHub <noreply@github.com>
Tue, 21 Jan 2020 12:26:47 +0000 (13:26 +0100)
Also, run such a suite in CI to make sure modules are working as expected
when used directly.

(partially cherry picked from 341c6d1b5abe4829f59fbc32e93f6a6a1afb900f)
(partially cherry picked from 437f389a24a6bef213d4df507909e7e69062300b)

Closes gh-4595
Ref gh-4550
Ref gh-4574

.travis.yml
Gruntfile.js
package.json
test/data/testinit-jsdom.js
test/data/testinit.js
test/index.html
test/jquery.js
test/karma.context.html
test/karma.debug.html

index 214a809781888953cb4c74dcf19288c1acd2649d..43891aeb1804cb3ffd1fb06f159750858d8016e4 100644 (file)
@@ -17,6 +17,13 @@ matrix:
       addons:
         chrome: stable
         firefox: latest
+    # 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:
index 27f3c02f6f153b0c2e08afc0f7a50bbfbbb274b6..b91fa1bed16fc354c13bc91866662a235709590b 100644 (file)
@@ -165,6 +165,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",
                                        "external/sinon/sinon.js",
@@ -174,39 +182,30 @@ 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/**", included: false, served: true },
-                                       { pattern: "external/**", included: false, served: true },
+                                       {
+                                               pattern: "dist/jquery.*",
+                                               included: false,
+                                               served: true,
+                                               nocache: true
+                                       },
+                                       {
+                                               pattern: "src/**",
+                                               included: false,
+                                               served: true,
+                                               nocache: true
+                                       },
+                                       {
+                                               pattern: "external/**",
+                                               included: false,
+                                               served: true,
+                                               nocache: true
+                                       },
+                                       { pattern: "node_modules/**", included: false, served: true },
                                        {
                                                pattern: "test/**/*.@(js|css|jpg|html|xml|svg)",
                                                included: false,
-                                               served: true
+                                               served: true,
+                                               nocache: true
                                        }
                                ],
                                reporters: [ "dots" ],
@@ -218,6 +217,21 @@ module.exports = function( grunt ) {
                        main: {
                                browsers: isTravis && travisBrowsers || [ "ChromeHeadless", "FirefoxHeadless" ]
                        },
+                       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: {
@@ -229,7 +243,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
index 9e1dcfafc433a37a70ed0ee16e36858cc5d5e5ae..2de617df7892a6b3bc99284fb901c344f880109a 100644 (file)
@@ -71,7 +71,8 @@
     "start": "grunt watch",
     "test:browserless": "grunt && grunt test:slow",
     "test:browser": "grunt && grunt karma:main",
-    "test": "grunt && grunt test:slow && grunt karma:main",
+    "test:amd": "grunt && grunt karma:amd",
+    "test": "grunt && grunt test:slow && grunt karma:main && grunt karma:amd",
     "jenkins": "npm run test:browserless"
   },
   "commitplease": {
index e0830cc9254b6035114cf0dc63e8121111f6befd..bedf093a9bfa1c67b2bca0ca58a366fb4a5f4cc9 100644 (file)
@@ -38,3 +38,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();
+       } );
+};
index e1d81c5c7a26c4e27cdce6680a61a4be73432015..6938fed244af86cc14c3c04d666b66ac64ffd8ac 100644 (file)
@@ -299,14 +299,16 @@ moduleTypeSupported();
 
 this.loadTests = function() {
 
-       // Directly load tests that need synchronous evaluation
-       if ( !QUnit.urlParams.amd || document.readyState === "loading" ) {
+       // 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;
+
+       // Directly load tests that need evaluation before DOMContentLoaded.
+       if ( !amd || document.readyState === "loading" ) {
                document.write( "<script src='" + parentUrl + "test/unit/ready.js'><\x2Fscript>" );
        } else {
                QUnit.module( "ready", function() {
-                       QUnit.test( "jQuery ready", function( assert ) {
-                               assert.ok( false, "Test should be initialized before DOM ready" );
-                       } );
+                       QUnit.skip( "jQuery ready tests skipped in async mode", function() {} );
                } );
        }
 
@@ -360,7 +362,11 @@ this.loadTests = function() {
                                }
 
                        } else {
-                               QUnit.load();
+                               if ( window.__karma__ && window.__karma__.start ) {
+                                       window.__karma__.start();
+                               } else {
+                                       QUnit.load();
+                               }
 
                                /**
                                 * Run in noConflict mode
index 7b5b302a984200ddd84ad6c751d4ea6f44276a81..3c4ba589dbb386778fdab476f4bbf36c93799d5d 100644 (file)
                // 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.amd ) {
+               // 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;
+
+               // 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 ( !amd ) {
                        loadTests();
                }
        </script>
index 6b1aef42f6c8bda2f0435900ce9613a1d149b515..bb4ae6fe4b182115c773d6de9396094f4dc26104 100644 (file)
@@ -2,44 +2,57 @@
 ( function() {
        /* global loadTests: false */
 
-       var FILEPATH = "/test/jquery.js",
+       var config, src,
+               FILEPATH = "/test/jquery.js",
                activeScript = [].slice.call( document.getElementsByTagName( "script" ), -1 )[ 0 ],
                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 :
-                       { dev: true },
-               src = urlParams.dev ?
-                       "dist/jquery.js" :
-                       "dist/jquery.min.js";
+       function getQUnitConfig() {
+               var config = Object.create( null );
 
-       // Define configuration parameters controlling how jQuery is loaded
-       if ( QUnit ) {
+               // Default to unminified jQuery for directly-opened iframes
+               if ( !QUnit ) {
+                       config.dev = true;
+               } else {
 
-               // AMD loading is asynchronous and incompatible with synchronous test loading in Karma
-               if ( !window.__karma__ ) {
-                       QUnit.config.urlConfig.push( {
-                               id: "amd",
-                               label: "Load with AMD",
-                               tooltip: "Load the AMD jQuery file (and its dependencies)"
+                       // QUnit.config is populated from QUnit.urlParams but only at the beginning
+                       // of the test run. We need to read both.
+                       QUnit.config.urlConfig.forEach( function( entry ) {
+                               config[ entry.id ] = QUnit.config[ entry.id ] != null ?
+                                       QUnit.config[ entry.id ] :
+                                       QUnit.urlParams[ entry.id ];
                        } );
                }
 
+               return config;
+       }
+
+       // Define configuration parameters controlling how jQuery is loaded
+       if ( QUnit ) {
                QUnit.config.urlConfig.push( {
+                       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"
                } );
        }
 
+       config = getQUnitConfig();
+
+       src = config.dev ?
+               "dist/jquery.js" :
+               "dist/jquery.min.js";
+
        // Honor AMD 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.amd && window.QUnit ) {
+       if ( config.amd && QUnit ) {
                require.config( {
                        baseUrl: parentUrl
                } );
index e4f8a4f88541962af7d2c7cb329fffcd4e185d53..4d340573dccbab1f7fdf7469ea30436f112620a3 100644 (file)
@@ -1,45 +1,43 @@
 <!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 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 ( !amd ) {
+                       loadTests();
+               }
+       </script>
 </body>
 </html>
index 950064db72972ff7c920906c750635368c255e1d..39acd9ccbd20c7c629b587b4dc35b2a20e9452a6 100644 (file)
@@ -2,46 +2,44 @@
 <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/external/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/external/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 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 ( !amd ) {
+                       loadTests();
+               }
+       </script>
 </body>
 </html>