How to test if jQuery 3.0 beta is Promises/A+ compatible in browser?

和自甴很熟 提交于 2019-11-28 13:06:49

The adapter referenced in the comments means adapting the jQuery deferred constructor to meet the API in the spec. The way to do so might be as follows (taken more or less from here):

var promisesAplusTests = require("promises-aplus-tests");
var jq                 = require('jquery');
var jsdom              = require('jsdom');
jsdom.env('<p></p>', function(err, window) {
    if (err != null) {
        throw err;
    } else {
        var $ = jq(window);
        var adapter = {};
        adapter.deferred = function() {
            var deferred = $.Deferred();

            return {
                promise: deferred.promise(),
                resolve: deferred.resolve.bind( deferred ),
                reject: deferred.reject.bind( deferred )
            };
        };
        promisesAplusTests(adapter, function (err) {
            // All done; output is in the console. 
            // Or check `err` for number of failures:
            if (err) {
                console.log(err);
            }
        });
    }
});

At which point you need to install the dependencies via npm and run the file. Note that using jquery requires a proper document (hence the need for jsdom).

Or you could take the easy route:

  • git clone the jquery repo
  • cd jquery directory
  • npm install
  • wait forever for it to finish, ignore all warnings
  • npm test -which runs the jquery unit tests (including A+ suite)

Running in the browser, despite the glib comment in the spec readme, will involve some of work. You will need to use a commonJS module loader like browserify. Browserify will shim the native node assertion library and I believe filesystem api. Mocha should work fine in the browser. Then the above code should run.

If you want to avoid node.js entirely (and not just for running the tests) , you'll have more work to do.

Step 1. Find or write a compatible assertion library and include it in a script tag.

Step 2. Include mocha in a script tag.

Step 3. Write your own stubs for require, assert, fs, etc. Each of those is a question in its own right.

Step 4. Use the adapter code.

Whether its worth doing all that or not to avoid node is your call.

The biggest difference between A+ compliant Promises and old jQuery Deferreds is that A+ Promises have proper error handling. You can verify that jQuery 3 promises now have proper error handling by running this simple test.

function test(name, $) {
  var $name = $('<td>').text(name);
  var $result = $('<td>');
  var $row = $('<tr>')
      .append($name)
      .append($result)
      .appendTo('tbody');
  
  var def = $.Deferred();
  def.rejectWith(new Error("Error"));
  def.then(undefined, function() {
    $result.text('Fail').css('color', 'red'); // This will be overriden by success case
  }).then(function() {
    $result.text('Success').css('color', 'green');
  });
}

test('jQuery 1', $1);
test('jQuery 2', $2);
test('jQuery 3', $3);
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script>
  var $1 = $;
  $.noConflict();
</script>
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<script>
  var $2 = $;
  $.noConflict();
</script>
<script src="https://code.jquery.com/jquery-3.0.0-beta1.js"></script>
<script>
  var $3 = $;
  $.noConflict();
</script>

<table>
  <thead>
    <tr>
      <td>Version</td>
      <td>Result</td>
    </tr>
  </thead>
  <tbody>
    </tbody>
</table>

How to run the tests in browser, without nodejs to verify ?


Note, have not yet achieved running tests in browser without nodejs. @JaredSmith 's assistance was essential to running tests at all using nodejs.

Have been able to achieve requirement described at Question by utilizing and adjusting files at Unofficial mirror of the WebKit SVN repository -> master -> LayoutTests -> js -> promises-tests.

Attempted to change as little as possible. Updated promises-tests version to 2.1.1 from 2.0.5 that was present at webkit repo; included .js files from other portions of repo to resources directory; added jQuery-3.0.0-pre source within adapter.js; commented promises-in-workers.html which tests Promise in Worker environment where jQuery() initialization checks document features.

Run tests by downloading jquery-3.0.0-promises-tests-in-browser, opening index.html in browser.

$(document).ready(function() {
  $("title, h3")
  .html("jQuery version " + jQuery().jquery + " Promises/A+ Compliance Tests");
  var tests = ["promises-tests-2-1-2.html"
               , "promises-tests-2-1-3.html"
               , "promises-tests-2-2-1.html"
               , "promises-tests-2-2-2.html"
               , "promises-tests-2-2-3.html"
               , "promises-tests-2-2-4.html"
               , "promises-tests-2-2-5.html"
               , "promises-tests-2-2-6.html"
               , "promises-tests-2-2-7.html"
               , "promises-tests-2-3-1.html"
               , "promises-tests-2-3-2.html"
               , "promises-tests-2-3-3.html"
               , "promises-tests-2-3-4.html"
               , "Promise-types.html" 
               // TODO test `jQuery.Deferred()` in `Worker` 
               // see http://stackoverflow.com/q/10491448/
               /* , "promises-in-workers.html" */ ];
  $.each(tests, function(index, test) {
    $("<iframe>", {
        width: "100%"
      }).on("load", function(e) {
        setTimeout(function() {
          e.target.height = e.target.contentWindow
                            .document.body.scrollHeight * 1.1 + "px";
        }, 2000 * (1 + index));
        // if (index === tests.length - 1) {
        //    $(e.target.contentWindow.document.body)
        //    .prepend("<span style='font-family:Times New Roman'>"
        //               + "Promises in Workers Test</span>")
        // }
      })
      .attr("src", test).appendTo("body")
  })
});

Demonstration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!