Skip to content

Commit

Permalink
Support jQuery >= 3.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mgol committed Mar 14, 2016
1 parent c0d8876 commit fcdace6
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Promise.resolve(2).should.eventually.be.within(Promise.resolve(1), Promise.resol

### Compatibility

Chai as Promised is compatible with all promises following the [Promises/A+ specification][spec]. Notably, jQuery's so-called “promises” are not up to spec, and Chai as Promised will not work with them. In particular, Chai as Promised makes extensive use of the standard [transformation behavior][] of `then`, which jQuery does not support.
Chai as Promised is compatible with all promises following the [Promises/A+ specification][spec]. Notably, jQuery's promises were not up to spec before jQuery 3.0, and Chai as Promised will not work with them. In particular, Chai as Promised makes extensive use of the standard [transformation behavior][] of `then`, which jQuery<3.0 does not support.

### Working with Non-Promise–Friendly Test Runners

Expand Down
14 changes: 9 additions & 5 deletions lib/chai-as-promised.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@
var Assertion = chai.Assertion;
var assert = chai.assert;

function isJQueryPromise(thenable) {
return typeof thenable.always === "function" &&
function isLegacyJQueryPromise(thenable) {
// jQuery promises are Promises/A+-compatible since 3.0.0. jQuery 3.0.0 is also the first version
// to define the catch method.
return typeof thenable.catch !== "function" &&
typeof thenable.always === "function" &&
typeof thenable.done === "function" &&
typeof thenable.fail === "function" &&
typeof thenable.pipe === "function" &&
Expand All @@ -47,9 +50,10 @@
if (typeof assertion._obj.then !== "function") {
throw new TypeError(utils.inspect(assertion._obj) + " is not a thenable.");
}
if (isJQueryPromise(assertion._obj)) {
throw new TypeError("Chai as Promised is incompatible with jQuery's thenables, sorry! Please use a " +
"Promises/A+ compatible library (see http://promisesaplus.com/).");
if (isLegacyJQueryPromise(assertion._obj)) {
throw new TypeError("Chai as Promised is incompatible with thenables of jQuery<3.0.0, sorry! Please " +
"upgrade jQuery or use another Promises/A+ compatible library (see " +
"http://promisesaplus.com/).");
}
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"test": "npm run test-plugin && npm run test-intercompatibility",
"test-plugin": "mocha",
"test-intercompatibility": "mocha test-intercompatibility --opts test-intercompatibility/mocha.opts",
"test-browser-jquery": "coffee ./test/browser/runner.coffee jquery",
"test-browser-q": "coffee ./test/browser/runner.coffee q",
"test-browser-when": "coffee ./test/browser/runner.coffee when",
"lint": "jshint ./lib",
Expand Down
29 changes: 29 additions & 0 deletions test/browser/libraries/jquery.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use strict"

exports.name = "jQuery"

exports.uri = "https://code.jquery.com/jquery-3.0.0-beta1.js"

exports.adapter = """
global.fulfilledPromise = function (value) {
var deferred = jQuery.Deferred();
deferred.resolve(value);
return deferred.promise();
};
global.rejectedPromise = function (reason) {
var deferred = jQuery.Deferred();
deferred.reject(reason);
return deferred.promise();
};
global.defer = jQuery.Deferred;
global.getPromise = function (deferred) {
return deferred.promise();
};
global.waitAll = function (promises) {
return jQuery.when
.apply(null, promises)
.then(function () {
return Array.prototype.slice.call(arguments);
});
};
"""
3 changes: 3 additions & 0 deletions test/browser/libraries/q.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ exports.adapter = """
global.fulfilledPromise = Q;
global.rejectedPromise = Q.reject;
global.defer = Q.defer;
global.getPromise = function (deferred) {
return deferred.promise;
};
global.waitAll = Q.all;
"""
5 changes: 4 additions & 1 deletion test/browser/libraries/when.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

exports.name = "when.js"

exports.uri = "https://rawgithub.com/cujojs/when/master/when.js"
exports.uri = "https://rawgit.com/cujojs/when/master/when.js"

# This shim is described in the when.js readme for use without module loaders.
exports.shim = """
Expand All @@ -25,5 +25,8 @@ exports.adapter = """
return deferred.promise;
};
global.defer = when.defer;
global.getPromise = function (deferred) {
return deferred.promise;
};
global.waitAll = when.all;
"""
2 changes: 1 addition & 1 deletion test/should-promise-specific.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ describe "Promise-specific extensions:", =>
describe "With promises that only become rejected later (GH-24)", =>
it "should wait for them", (done) =>
deferred = defer()
deferred.promise.should.be.rejectedWith("error message").and.notify(done)
getPromise(deferred).should.be.rejectedWith("error message").and.notify(done)

setTimeout(
=> deferred.reject(new Error("error message"))
Expand Down

0 comments on commit fcdace6

Please sign in to comment.