chai-as-promised 5.3.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +1 -1
- package/README.md +17 -22
- package/lib/chai-as-promised.js +321 -322
- package/package.json +5 -5
    
        package/LICENSE.txt
    CHANGED
    
    
    
        package/README.md
    CHANGED
    
    | @@ -124,7 +124,7 @@ chaiAsPromised.transformAsserterArgs = function (args) { | |
| 124 124 | 
             
            }
         | 
| 125 125 |  | 
| 126 126 | 
             
            Promise.resolve(2).should.eventually.equal(2); // will now fail!
         | 
| 127 | 
            -
            Promise.resolve( | 
| 127 | 
            +
            Promise.resolve(3).should.eventually.equal(2); // will now pass!
         | 
| 128 128 | 
             
            ```
         | 
| 129 129 |  | 
| 130 130 | 
             
            The transform can even be asynchronous, returning a promise for an array instead of an array directly. An example of that might be using `Promise.all` so that an array of promises becomes a promise for an array. If you do that, then you can compare promises against other promises using the asserters:
         | 
| @@ -144,7 +144,11 @@ Promise.resolve(2).should.eventually.be.within(Promise.resolve(1), Promise.resol | |
| 144 144 |  | 
| 145 145 | 
             
            ### Compatibility
         | 
| 146 146 |  | 
| 147 | 
            -
            Chai as Promised is compatible with all promises following the [Promises/A+ specification][spec]. | 
| 147 | 
            +
            Chai as Promised is compatible with all promises following the [Promises/A+ specification][spec].
         | 
| 148 | 
            +
             | 
| 149 | 
            +
            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.
         | 
| 150 | 
            +
             | 
| 151 | 
            +
            Angular promises have a special digest cycle for their processing, and [need extra setup code to work with Chai as Promised](http://stackoverflow.com/a/37374041/3191).
         | 
| 148 152 |  | 
| 149 153 | 
             
            ### Working with Non-Promise–Friendly Test Runners
         | 
| 150 154 |  | 
| @@ -202,31 +206,21 @@ var chai = require("chai"); | |
| 202 206 | 
             
            var chaiAsPromised = require("chai-as-promised");
         | 
| 203 207 |  | 
| 204 208 | 
             
            chai.use(chaiAsPromised);
         | 
| 205 | 
            -
            ```
         | 
| 206 | 
            -
             | 
| 207 | 
            -
            You can of course put this code in a common test fixture file; for an example using [Mocha][], see [the Chai as Promised tests themselves][fixturedemo].
         | 
| 208 | 
            -
             | 
| 209 | 
            -
            ### AMD
         | 
| 210 209 |  | 
| 211 | 
            -
             | 
| 212 | 
            -
             | 
| 213 | 
            -
             | 
| 214 | 
            -
             | 
| 215 | 
            -
             | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 218 | 
            -
                chai.use(chaiAsPromised);
         | 
| 219 | 
            -
            });
         | 
| 210 | 
            +
            // Then either:
         | 
| 211 | 
            +
            var expect = chai.expect;
         | 
| 212 | 
            +
            // or:
         | 
| 213 | 
            +
            var assert = chai.assert;
         | 
| 214 | 
            +
            // or:
         | 
| 215 | 
            +
            chai.should();
         | 
| 216 | 
            +
            // according to your preference of assertion style
         | 
| 220 217 | 
             
            ```
         | 
| 221 218 |  | 
| 222 | 
            -
             | 
| 219 | 
            +
            You can of course put this code in a common test fixture file; for an example using [Mocha][], see [the Chai as Promised tests themselves][fixturedemo].
         | 
| 223 220 |  | 
| 224 | 
            -
             | 
| 221 | 
            +
            ### In the Browser
         | 
| 225 222 |  | 
| 226 | 
            -
             | 
| 227 | 
            -
            <script src="chai.js"></script>
         | 
| 228 | 
            -
            <script src="chai-as-promised.js"></script>
         | 
| 229 | 
            -
            ```
         | 
| 223 | 
            +
            To use Chai as Promised in environments that don't support Node.js-like CommonJS modules, you'll need to use a bundling tool like [browserify][].
         | 
| 230 224 |  | 
| 231 225 | 
             
            ### Karma
         | 
| 232 226 |  | 
| @@ -250,3 +244,4 @@ Chai as Promised is only compatible with modern browsers (IE ≥9, Safari ≥6, | |
| 250 244 | 
             
            [sinon-chai]: https://github.com/domenic/sinon-chai
         | 
| 251 245 | 
             
            [Karma]: https://karma-runner.github.io/
         | 
| 252 246 | 
             
            [karma-chai-as-promised]: https://github.com/vlkosinov/karma-chai-as-promised
         | 
| 247 | 
            +
            [browserify]: http://browserify.org/
         | 
    
        package/lib/chai-as-promised.js
    CHANGED
    
    | @@ -1,375 +1,374 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
                 | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
                 | 
| 11 | 
            -
             | 
| 12 | 
            -
                     | 
| 13 | 
            -
             | 
| 14 | 
            -
                    });
         | 
| 15 | 
            -
                } else {
         | 
| 16 | 
            -
                    /*global self: false */
         | 
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
            var checkError = require("check-error");
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module.exports = function (chai, utils) {
         | 
| 5 | 
            +
                var Assertion = chai.Assertion;
         | 
| 6 | 
            +
                var assert = chai.assert;
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                // If we are using a version of Chai that has checkError on it,
         | 
| 9 | 
            +
                // we want to use that version to be consistent. Otherwise, we use
         | 
| 10 | 
            +
                // what was passed to the factory.
         | 
| 11 | 
            +
                if (utils.checkError) {
         | 
| 12 | 
            +
                    checkError = utils.checkError;
         | 
| 13 | 
            +
                }
         | 
| 17 14 |  | 
| 18 | 
            -
             | 
| 19 | 
            -
                     | 
| 15 | 
            +
                function isLegacyJQueryPromise(thenable) {
         | 
| 16 | 
            +
                    // jQuery promises are Promises/A+-compatible since 3.0.0. jQuery 3.0.0 is also the first version
         | 
| 17 | 
            +
                    // to define the catch method.
         | 
| 18 | 
            +
                    return typeof thenable.catch !== "function" &&
         | 
| 19 | 
            +
                           typeof thenable.always === "function" &&
         | 
| 20 | 
            +
                           typeof thenable.done === "function" &&
         | 
| 21 | 
            +
                           typeof thenable.fail === "function" &&
         | 
| 22 | 
            +
                           typeof thenable.pipe === "function" &&
         | 
| 23 | 
            +
                           typeof thenable.progress === "function" &&
         | 
| 24 | 
            +
                           typeof thenable.state === "function";
         | 
| 25 | 
            +
                }
         | 
| 20 26 |  | 
| 21 | 
            -
             | 
| 22 | 
            -
                     | 
| 27 | 
            +
                function assertIsAboutPromise(assertion) {
         | 
| 28 | 
            +
                    if (typeof assertion._obj.then !== "function") {
         | 
| 29 | 
            +
                        throw new TypeError(utils.inspect(assertion._obj) + " is not a thenable.");
         | 
| 30 | 
            +
                    }
         | 
| 31 | 
            +
                    if (isLegacyJQueryPromise(assertion._obj)) {
         | 
| 32 | 
            +
                        throw new TypeError("Chai as Promised is incompatible with thenables of jQuery<3.0.0, sorry! Please " +
         | 
| 33 | 
            +
                                            "upgrade jQuery or use another Promises/A+ compatible library (see " +
         | 
| 34 | 
            +
                                            "http://promisesaplus.com/).");
         | 
| 35 | 
            +
                    }
         | 
| 23 36 | 
             
                }
         | 
| 24 37 |  | 
| 25 | 
            -
                 | 
| 26 | 
            -
                     | 
| 27 | 
            -
             | 
| 38 | 
            +
                function method(name, asserter) {
         | 
| 39 | 
            +
                    utils.addMethod(Assertion.prototype, name, function () {
         | 
| 40 | 
            +
                        assertIsAboutPromise(this);
         | 
| 41 | 
            +
                        return asserter.apply(this, arguments);
         | 
| 42 | 
            +
                    });
         | 
| 43 | 
            +
                }
         | 
| 28 44 |  | 
| 29 | 
            -
                 | 
| 30 | 
            -
                     | 
| 31 | 
            -
             | 
| 45 | 
            +
                function property(name, asserter) {
         | 
| 46 | 
            +
                    utils.addProperty(Assertion.prototype, name, function () {
         | 
| 47 | 
            +
                        assertIsAboutPromise(this);
         | 
| 48 | 
            +
                        return asserter.apply(this, arguments);
         | 
| 49 | 
            +
                    });
         | 
| 50 | 
            +
                }
         | 
| 32 51 |  | 
| 33 | 
            -
                function  | 
| 34 | 
            -
                     | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
                    function isLegacyJQueryPromise(thenable) {
         | 
| 38 | 
            -
                        // jQuery promises are Promises/A+-compatible since 3.0.0. jQuery 3.0.0 is also the first version
         | 
| 39 | 
            -
                        // to define the catch method.
         | 
| 40 | 
            -
                        return typeof thenable.catch !== "function" &&
         | 
| 41 | 
            -
                               typeof thenable.always === "function" &&
         | 
| 42 | 
            -
                               typeof thenable.done === "function" &&
         | 
| 43 | 
            -
                               typeof thenable.fail === "function" &&
         | 
| 44 | 
            -
                               typeof thenable.pipe === "function" &&
         | 
| 45 | 
            -
                               typeof thenable.progress === "function" &&
         | 
| 46 | 
            -
                               typeof thenable.state === "function";
         | 
| 47 | 
            -
                    }
         | 
| 52 | 
            +
                function doNotify(promise, done) {
         | 
| 53 | 
            +
                    promise.then(function () { done(); }, done);
         | 
| 54 | 
            +
                }
         | 
| 48 55 |  | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
                        if (isLegacyJQueryPromise(assertion._obj)) {
         | 
| 54 | 
            -
                            throw new TypeError("Chai as Promised is incompatible with thenables of jQuery<3.0.0, sorry! Please " +
         | 
| 55 | 
            -
                                                "upgrade jQuery or use another Promises/A+ compatible library (see " +
         | 
| 56 | 
            -
                                                "http://promisesaplus.com/).");
         | 
| 57 | 
            -
                        }
         | 
| 58 | 
            -
                    }
         | 
| 56 | 
            +
                // These are for clarity and to bypass Chai refusing to allow `undefined` as actual when used with `assert`.
         | 
| 57 | 
            +
                function assertIfNegated(assertion, message, extra) {
         | 
| 58 | 
            +
                    assertion.assert(true, null, message, extra.expected, extra.actual);
         | 
| 59 | 
            +
                }
         | 
| 59 60 |  | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
                            return asserter.apply(this, arguments);
         | 
| 64 | 
            -
                        });
         | 
| 65 | 
            -
                    }
         | 
| 61 | 
            +
                function assertIfNotNegated(assertion, message, extra) {
         | 
| 62 | 
            +
                    assertion.assert(false, message, null, extra.expected, extra.actual);
         | 
| 63 | 
            +
                }
         | 
| 66 64 |  | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
                     | 
| 65 | 
            +
                function getBasePromise(assertion) {
         | 
| 66 | 
            +
                    // We need to chain subsequent asserters on top of ones in the chain already (consider
         | 
| 67 | 
            +
                    // `eventually.have.property("foo").that.equals("bar")`), only running them after the existing ones pass.
         | 
| 68 | 
            +
                    // So the first base-promise is `assertion._obj`, but after that we use the assertions themselves, i.e.
         | 
| 69 | 
            +
                    // previously derived promises, to chain off of.
         | 
| 70 | 
            +
                    return typeof assertion.then === "function" ? assertion : assertion._obj;
         | 
| 71 | 
            +
                }
         | 
| 73 72 |  | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 73 | 
            +
                function getReasonName(reason) {
         | 
| 74 | 
            +
                    return (reason instanceof Error) ? reason.toString() : checkError.getConstructorName(reason);
         | 
| 75 | 
            +
                }
         | 
| 77 76 |  | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 77 | 
            +
                // Grab these first, before we modify `Assertion.prototype`.
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                var propertyNames = Object.getOwnPropertyNames(Assertion.prototype);
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                var propertyDescs = {};
         | 
| 82 | 
            +
                propertyNames.forEach(function (name) {
         | 
| 83 | 
            +
                    propertyDescs[name] = Object.getOwnPropertyDescriptor(Assertion.prototype, name);
         | 
| 84 | 
            +
                });
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                property("fulfilled", function () {
         | 
| 87 | 
            +
                    var that = this;
         | 
| 88 | 
            +
                    var derivedPromise = getBasePromise(that).then(
         | 
| 89 | 
            +
                        function (value) {
         | 
| 90 | 
            +
                            assertIfNegated(that,
         | 
| 91 | 
            +
                                            "expected promise not to be fulfilled but it was fulfilled with #{act}",
         | 
| 92 | 
            +
                                            { actual: value });
         | 
| 93 | 
            +
                            return value;
         | 
| 94 | 
            +
                        },
         | 
| 95 | 
            +
                        function (reason) {
         | 
| 96 | 
            +
                            assertIfNotNegated(that,
         | 
| 97 | 
            +
                                               "expected promise to be fulfilled but it was rejected with #{act}",
         | 
| 98 | 
            +
                                               { actual: getReasonName(reason) });
         | 
| 99 | 
            +
                            return reason;
         | 
| 100 | 
            +
                        }
         | 
| 101 | 
            +
                    );
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                    module.exports.transferPromiseness(that, derivedPromise);
         | 
| 104 | 
            +
                });
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                property("rejected", function () {
         | 
| 107 | 
            +
                    var that = this;
         | 
| 108 | 
            +
                    var derivedPromise = getBasePromise(that).then(
         | 
| 109 | 
            +
                        function (value) {
         | 
| 110 | 
            +
                            assertIfNotNegated(that,
         | 
| 111 | 
            +
                                               "expected promise to be rejected but it was fulfilled with #{act}",
         | 
| 112 | 
            +
                                               { actual: value });
         | 
| 113 | 
            +
                            return value;
         | 
| 114 | 
            +
                        },
         | 
| 115 | 
            +
                        function (reason) {
         | 
| 116 | 
            +
                            assertIfNegated(that,
         | 
| 117 | 
            +
                                            "expected promise not to be rejected but it was rejected with #{act}",
         | 
| 118 | 
            +
                                            { actual: getReasonName(reason) });
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                            // Return the reason, transforming this into a fulfillment, to allow further assertions, e.g.
         | 
| 121 | 
            +
                            // `promise.should.be.rejected.and.eventually.equal("reason")`.
         | 
| 122 | 
            +
                            return reason;
         | 
| 123 | 
            +
                        }
         | 
| 124 | 
            +
                    );
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                    module.exports.transferPromiseness(that, derivedPromise);
         | 
| 127 | 
            +
                });
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                method("rejectedWith", function (errorLike, errMsgMatcher, message) {
         | 
| 130 | 
            +
                    var errorLikeName = null;
         | 
| 131 | 
            +
                    var negate = utils.flag(this, "negate") || false;
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                    // rejectedWith with that is called without arguments is
         | 
| 134 | 
            +
                    // the same as a plain ".rejected" use.
         | 
| 135 | 
            +
                    if (errorLike === undefined && errMsgMatcher === undefined &&
         | 
| 136 | 
            +
                        message === undefined) {
         | 
| 137 | 
            +
                        /* jshint expr: true */
         | 
| 138 | 
            +
                        this.rejected;
         | 
| 139 | 
            +
                        return;
         | 
| 81 140 | 
             
                    }
         | 
| 82 141 |  | 
| 83 | 
            -
                     | 
| 84 | 
            -
                         | 
| 142 | 
            +
                    if (message !== undefined) {
         | 
| 143 | 
            +
                        utils.flag(this, "message", message);
         | 
| 85 144 | 
             
                    }
         | 
| 86 145 |  | 
| 87 | 
            -
                     | 
| 88 | 
            -
                         | 
| 89 | 
            -
                         | 
| 90 | 
            -
             | 
| 91 | 
            -
                         | 
| 92 | 
            -
             | 
| 146 | 
            +
                    if (errorLike instanceof RegExp || typeof errorLike === "string") {
         | 
| 147 | 
            +
                        errMsgMatcher = errorLike;
         | 
| 148 | 
            +
                        errorLike = null;
         | 
| 149 | 
            +
                    } else if (errorLike && errorLike instanceof Error) {
         | 
| 150 | 
            +
                        errorLikeName = errorLike.toString();
         | 
| 151 | 
            +
                    } else if (typeof errorLike === "function") {
         | 
| 152 | 
            +
                        errorLikeName = checkError.getConstructorName(errorLike);
         | 
| 153 | 
            +
                    } else {
         | 
| 154 | 
            +
                        errorLike = null;
         | 
| 93 155 | 
             
                    }
         | 
| 156 | 
            +
                    var everyArgIsDefined = Boolean(errorLike && errMsgMatcher);
         | 
| 94 157 |  | 
| 95 | 
            -
                     | 
| 96 | 
            -
             | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
                    var propertyDescs = {};
         | 
| 100 | 
            -
                    propertyNames.forEach(function (name) {
         | 
| 101 | 
            -
                        propertyDescs[name] = Object.getOwnPropertyDescriptor(Assertion.prototype, name);
         | 
| 102 | 
            -
                    });
         | 
| 158 | 
            +
                    var matcherRelation = "including";
         | 
| 159 | 
            +
                    if (errMsgMatcher instanceof RegExp) {
         | 
| 160 | 
            +
                        matcherRelation = "matching";
         | 
| 161 | 
            +
                    }
         | 
| 103 162 |  | 
| 104 | 
            -
                     | 
| 105 | 
            -
             | 
| 106 | 
            -
                         | 
| 107 | 
            -
                             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
                             | 
| 115 | 
            -
                                 | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 163 | 
            +
                    var that = this;
         | 
| 164 | 
            +
                    var derivedPromise = getBasePromise(that).then(
         | 
| 165 | 
            +
                        function (value) {
         | 
| 166 | 
            +
                            var assertionMessage = null;
         | 
| 167 | 
            +
                            var expected = null;
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                            if (errorLike) {
         | 
| 170 | 
            +
                                assertionMessage = "expected promise to be rejected with #{exp} but it was fulfilled with " +
         | 
| 171 | 
            +
                                                   "#{act}";
         | 
| 172 | 
            +
                                expected = errorLikeName;
         | 
| 173 | 
            +
                            } else if (errMsgMatcher) {
         | 
| 174 | 
            +
                                assertionMessage = "expected promise to be rejected with an error " + matcherRelation +
         | 
| 175 | 
            +
                                    " #{exp} but it was fulfilled with #{act}";
         | 
| 176 | 
            +
                                expected = errMsgMatcher;
         | 
| 118 177 | 
             
                            }
         | 
| 119 | 
            -
                        );
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                        chaiAsPromised.transferPromiseness(that, derivedPromise);
         | 
| 122 | 
            -
                    });
         | 
| 123 178 |  | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
                         | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
                             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
                        chaiAsPromised.transferPromiseness(that, derivedPromise);
         | 
| 146 | 
            -
                    });
         | 
| 147 | 
            -
             | 
| 148 | 
            -
                    method("rejectedWith", function (Constructor, message) {
         | 
| 149 | 
            -
                        var desiredReason = null;
         | 
| 150 | 
            -
                        var constructorName = null;
         | 
| 151 | 
            -
             | 
| 152 | 
            -
                        if (Constructor instanceof RegExp || typeof Constructor === "string") {
         | 
| 153 | 
            -
                            message = Constructor;
         | 
| 154 | 
            -
                            Constructor = null;
         | 
| 155 | 
            -
                        } else if (Constructor && Constructor instanceof Error) {
         | 
| 156 | 
            -
                            desiredReason = Constructor;
         | 
| 157 | 
            -
                            Constructor = null;
         | 
| 158 | 
            -
                            message = null;
         | 
| 159 | 
            -
                        } else if (typeof Constructor === "function") {
         | 
| 160 | 
            -
                            constructorName = (new Constructor()).name;
         | 
| 161 | 
            -
                        } else {
         | 
| 162 | 
            -
                            Constructor = null;
         | 
| 163 | 
            -
                        }
         | 
| 164 | 
            -
             | 
| 165 | 
            -
                        var that = this;
         | 
| 166 | 
            -
                        var derivedPromise = getBasePromise(that).then(
         | 
| 167 | 
            -
                            function (value) {
         | 
| 168 | 
            -
                                var assertionMessage = null;
         | 
| 169 | 
            -
                                var expected = null;
         | 
| 170 | 
            -
             | 
| 171 | 
            -
                                if (Constructor) {
         | 
| 172 | 
            -
                                    assertionMessage = "expected promise to be rejected with #{exp} but it was fulfilled with " +
         | 
| 173 | 
            -
                                                       "#{act}";
         | 
| 174 | 
            -
                                    expected = constructorName;
         | 
| 175 | 
            -
                                } else if (message) {
         | 
| 176 | 
            -
                                    var verb = message instanceof RegExp ? "matching" : "including";
         | 
| 177 | 
            -
                                    assertionMessage = "expected promise to be rejected with an error " + verb + " #{exp} but it " +
         | 
| 178 | 
            -
                                                       "was fulfilled with #{act}";
         | 
| 179 | 
            -
                                    expected = message;
         | 
| 180 | 
            -
                                } else if (desiredReason) {
         | 
| 181 | 
            -
                                    assertionMessage = "expected promise to be rejected with #{exp} but it was fulfilled with " +
         | 
| 182 | 
            -
                                                       "#{act}";
         | 
| 183 | 
            -
                                    expected = desiredReason;
         | 
| 179 | 
            +
                            assertIfNotNegated(that, assertionMessage, { expected: expected, actual: value });
         | 
| 180 | 
            +
                            return value;
         | 
| 181 | 
            +
                        },
         | 
| 182 | 
            +
                        function (reason) {
         | 
| 183 | 
            +
                            var errorLikeCompatible = errorLike && (errorLike instanceof Error ?
         | 
| 184 | 
            +
                                                                    checkError.compatibleInstance(reason, errorLike) :
         | 
| 185 | 
            +
                                                                    checkError.compatibleConstructor(reason, errorLike));
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                            var errMsgMatcherCompatible = errMsgMatcher && checkError.compatibleMessage(reason, errMsgMatcher);
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                            var reasonName = getReasonName(reason);
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                            if (negate && everyArgIsDefined) {
         | 
| 192 | 
            +
                                if (errorLikeCompatible && errMsgMatcherCompatible) {
         | 
| 193 | 
            +
                                    that.assert(true,
         | 
| 194 | 
            +
                                                null,
         | 
| 195 | 
            +
                                                "expected promise not to be rejected with #{exp} but it was rejected " +
         | 
| 196 | 
            +
                                                "with #{act}",
         | 
| 197 | 
            +
                                                errorLikeName,
         | 
| 198 | 
            +
                                                reasonName);
         | 
| 184 199 | 
             
                                }
         | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 189 | 
            -
                            },
         | 
| 190 | 
            -
                            function (reason) {
         | 
| 191 | 
            -
                                if (Constructor) {
         | 
| 192 | 
            -
                                    that.assert(reason instanceof Constructor,
         | 
| 200 | 
            +
                            }
         | 
| 201 | 
            +
                            else {
         | 
| 202 | 
            +
                                if (errorLike) {
         | 
| 203 | 
            +
                                    that.assert(errorLikeCompatible,
         | 
| 193 204 | 
             
                                                "expected promise to be rejected with #{exp} but it was rejected with #{act}",
         | 
| 194 | 
            -
                                                "expected promise not to be rejected with #{exp} but it was rejected  | 
| 195 | 
            -
                                                 | 
| 196 | 
            -
                                                 | 
| 205 | 
            +
                                                "expected promise not to be rejected with #{exp} but it was rejected " +
         | 
| 206 | 
            +
                                                "with #{act}",
         | 
| 207 | 
            +
                                                errorLikeName,
         | 
| 208 | 
            +
                                                reasonName);
         | 
| 197 209 | 
             
                                }
         | 
| 198 210 |  | 
| 199 | 
            -
                                 | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 202 | 
            -
             | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 205 | 
            -
             | 
| 206 | 
            -
             | 
| 207 | 
            -
                                                    message,
         | 
| 208 | 
            -
                                                    reasonMessage);
         | 
| 209 | 
            -
                                    }
         | 
| 210 | 
            -
                                    if (typeof message === "string") {
         | 
| 211 | 
            -
                                        that.assert(reasonMessage.indexOf(message) !== -1,
         | 
| 212 | 
            -
                                                    "expected promise to be rejected with an error including #{exp} but got #{act}",
         | 
| 213 | 
            -
                                                    "expected promise not to be rejected with an error including #{exp}",
         | 
| 214 | 
            -
                                                    message,
         | 
| 215 | 
            -
                                                    reasonMessage);
         | 
| 216 | 
            -
                                    }
         | 
| 217 | 
            -
                                }
         | 
| 218 | 
            -
             | 
| 219 | 
            -
                                if (desiredReason) {
         | 
| 220 | 
            -
                                    that.assert(reason === desiredReason,
         | 
| 221 | 
            -
                                                "expected promise to be rejected with #{exp} but it was rejected with #{act}",
         | 
| 222 | 
            -
                                                "expected promise not to be rejected with #{exp}",
         | 
| 223 | 
            -
                                                desiredReason,
         | 
| 224 | 
            -
                                                reason);
         | 
| 211 | 
            +
                                if (errMsgMatcher) {
         | 
| 212 | 
            +
                                    that.assert(errMsgMatcherCompatible,
         | 
| 213 | 
            +
                                                "expected promise to be rejected with an error " + matcherRelation +
         | 
| 214 | 
            +
                                                " #{exp} but got #{act}",
         | 
| 215 | 
            +
                                                "expected promise not to be rejected with an error " + matcherRelation +
         | 
| 216 | 
            +
                                                " #{exp}",
         | 
| 217 | 
            +
                                                errMsgMatcher,
         | 
| 218 | 
            +
                                                checkError.getMessage(reason));
         | 
| 225 219 | 
             
                                }
         | 
| 226 220 | 
             
                            }
         | 
| 227 | 
            -
                        );
         | 
| 228 221 |  | 
| 229 | 
            -
             | 
| 230 | 
            -
             | 
| 222 | 
            +
                            return reason;
         | 
| 223 | 
            +
                        }
         | 
| 224 | 
            +
                    );
         | 
| 231 225 |  | 
| 232 | 
            -
                     | 
| 233 | 
            -
             | 
| 234 | 
            -
                    });
         | 
| 226 | 
            +
                    module.exports.transferPromiseness(that, derivedPromise);
         | 
| 227 | 
            +
                });
         | 
| 235 228 |  | 
| 236 | 
            -
             | 
| 237 | 
            -
             | 
| 238 | 
            -
             | 
| 229 | 
            +
                property("eventually", function () {
         | 
| 230 | 
            +
                    utils.flag(this, "eventually", true);
         | 
| 231 | 
            +
                });
         | 
| 239 232 |  | 
| 240 | 
            -
             | 
| 241 | 
            -
             | 
| 242 | 
            -
             | 
| 233 | 
            +
                method("notify", function (done) {
         | 
| 234 | 
            +
                    doNotify(getBasePromise(this), done);
         | 
| 235 | 
            +
                });
         | 
| 243 236 |  | 
| 244 | 
            -
             | 
| 245 | 
            -
                     | 
| 237 | 
            +
                method("become", function (value, message) {
         | 
| 238 | 
            +
                    return this.eventually.deep.equal(value, message);
         | 
| 239 | 
            +
                });
         | 
| 246 240 |  | 
| 247 | 
            -
             | 
| 248 | 
            -
             | 
| 249 | 
            -
                        return name !== "assert" && typeof propertyDescs[name].value === "function";
         | 
| 250 | 
            -
                    });
         | 
| 241 | 
            +
                ////////
         | 
| 242 | 
            +
                // `eventually`
         | 
| 251 243 |  | 
| 252 | 
            -
             | 
| 253 | 
            -
             | 
| 254 | 
            -
             | 
| 255 | 
            -
             | 
| 256 | 
            -
                            };
         | 
| 257 | 
            -
                        });
         | 
| 258 | 
            -
                    });
         | 
| 244 | 
            +
                // We need to be careful not to trigger any getters, thus `Object.getOwnPropertyDescriptor` usage.
         | 
| 245 | 
            +
                var methodNames = propertyNames.filter(function (name) {
         | 
| 246 | 
            +
                    return name !== "assert" && typeof propertyDescs[name].value === "function";
         | 
| 247 | 
            +
                });
         | 
| 259 248 |  | 
| 260 | 
            -
             | 
| 261 | 
            -
             | 
| 249 | 
            +
                methodNames.forEach(function (methodName) {
         | 
| 250 | 
            +
                    Assertion.overwriteMethod(methodName, function (originalMethod) {
         | 
| 251 | 
            +
                        return function () {
         | 
| 252 | 
            +
                            doAsserterAsyncAndAddThen(originalMethod, this, arguments);
         | 
| 253 | 
            +
                        };
         | 
| 262 254 | 
             
                    });
         | 
| 263 | 
            -
             | 
| 264 | 
            -
             | 
| 265 | 
            -
             | 
| 266 | 
            -
             | 
| 267 | 
            -
             | 
| 268 | 
            -
             | 
| 269 | 
            -
             | 
| 270 | 
            -
             | 
| 271 | 
            -
             | 
| 272 | 
            -
             | 
| 273 | 
            -
             | 
| 274 | 
            -
             | 
| 275 | 
            -
             | 
| 276 | 
            -
             | 
| 277 | 
            -
             | 
| 278 | 
            -
             | 
| 279 | 
            -
             | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
                            ) | 
| 283 | 
            -
             | 
| 284 | 
            -
                            Assertion.overwriteProperty(getterName, function (originalGetter) {
         | 
| 285 | 
            -
                                return function () {
         | 
| 255 | 
            +
                });
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                var getterNames = propertyNames.filter(function (name) {
         | 
| 258 | 
            +
                    return name !== "_obj" && typeof propertyDescs[name].get === "function";
         | 
| 259 | 
            +
                });
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                getterNames.forEach(function (getterName) {
         | 
| 262 | 
            +
                    // Chainable methods are things like `an`, which can work both for `.should.be.an.instanceOf` and as
         | 
| 263 | 
            +
                    // `should.be.an("object")`. We need to handle those specially.
         | 
| 264 | 
            +
                    var isChainableMethod = Assertion.prototype.__methods.hasOwnProperty(getterName);
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                    if (isChainableMethod) {
         | 
| 267 | 
            +
                        Assertion.overwriteChainableMethod(
         | 
| 268 | 
            +
                            getterName,
         | 
| 269 | 
            +
                            function (originalMethod) {
         | 
| 270 | 
            +
                                return function() {
         | 
| 271 | 
            +
                                    doAsserterAsyncAndAddThen(originalMethod, this, arguments);
         | 
| 272 | 
            +
                                };
         | 
| 273 | 
            +
                            },
         | 
| 274 | 
            +
                            function (originalGetter) {
         | 
| 275 | 
            +
                                return function() {
         | 
| 286 276 | 
             
                                    doAsserterAsyncAndAddThen(originalGetter, this);
         | 
| 287 277 | 
             
                                };
         | 
| 288 | 
            -
                            } | 
| 289 | 
            -
                         | 
| 290 | 
            -
                    } | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
                        if (!utils.flag(assertion, "eventually")) {
         | 
| 296 | 
            -
                            return asserter.apply(assertion, args);
         | 
| 297 | 
            -
                        }
         | 
| 298 | 
            -
             | 
| 299 | 
            -
                        var derivedPromise = getBasePromise(assertion).then(function (value) {
         | 
| 300 | 
            -
                            // Set up the environment for the asserter to actually run: `_obj` should be the fulfillment value, and
         | 
| 301 | 
            -
                            // now that we have the value, we're no longer in "eventually" mode, so we won't run any of this code,
         | 
| 302 | 
            -
                            // just the base Chai code that we get to via the short-circuit above.
         | 
| 303 | 
            -
                            assertion._obj = value;
         | 
| 304 | 
            -
                            utils.flag(assertion, "eventually", false);
         | 
| 305 | 
            -
             | 
| 306 | 
            -
                            return args ? chaiAsPromised.transformAsserterArgs(args) : args;
         | 
| 307 | 
            -
                        }).then(function (args) {
         | 
| 308 | 
            -
                            asserter.apply(assertion, args);
         | 
| 309 | 
            -
             | 
| 310 | 
            -
                            // Because asserters, for example `property`, can change the value of `_obj` (i.e. change the "object"
         | 
| 311 | 
            -
                            // flag), we need to communicate this value change to subsequent chained asserters. Since we build a
         | 
| 312 | 
            -
                            // promise chain paralleling the asserter chain, we can use it to communicate such changes.
         | 
| 313 | 
            -
                            return assertion._obj;
         | 
| 278 | 
            +
                            }
         | 
| 279 | 
            +
                        );
         | 
| 280 | 
            +
                    } else {
         | 
| 281 | 
            +
                        Assertion.overwriteProperty(getterName, function (originalGetter) {
         | 
| 282 | 
            +
                            return function () {
         | 
| 283 | 
            +
                                doAsserterAsyncAndAddThen(originalGetter, this);
         | 
| 284 | 
            +
                            };
         | 
| 314 285 | 
             
                        });
         | 
| 286 | 
            +
                    }
         | 
| 287 | 
            +
                });
         | 
| 315 288 |  | 
| 316 | 
            -
             | 
| 289 | 
            +
                function doAsserterAsyncAndAddThen(asserter, assertion, args) {
         | 
| 290 | 
            +
                    // Since we're intercepting all methods/properties, we need to just pass through if they don't want
         | 
| 291 | 
            +
                    // `eventually`, or if we've already fulfilled the promise (see below).
         | 
| 292 | 
            +
                    if (!utils.flag(assertion, "eventually")) {
         | 
| 293 | 
            +
                        return asserter.apply(assertion, args);
         | 
| 317 294 | 
             
                    }
         | 
| 318 295 |  | 
| 319 | 
            -
                     | 
| 320 | 
            -
             | 
| 321 | 
            -
             | 
| 322 | 
            -
                         | 
| 296 | 
            +
                    var derivedPromise = getBasePromise(assertion).then(function (value) {
         | 
| 297 | 
            +
                        // Set up the environment for the asserter to actually run: `_obj` should be the fulfillment value, and
         | 
| 298 | 
            +
                        // now that we have the value, we're no longer in "eventually" mode, so we won't run any of this code,
         | 
| 299 | 
            +
                        // just the base Chai code that we get to via the short-circuit above.
         | 
| 300 | 
            +
                        assertion._obj = value;
         | 
| 301 | 
            +
                        utils.flag(assertion, "eventually", false);
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                        return args ? module.exports.transformAsserterArgs(args) : args;
         | 
| 304 | 
            +
                    }).then(function (args) {
         | 
| 305 | 
            +
                        asserter.apply(assertion, args);
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                        // Because asserters, for example `property`, can change the value of `_obj` (i.e. change the "object"
         | 
| 308 | 
            +
                        // flag), we need to communicate this value change to subsequent chained asserters. Since we build a
         | 
| 309 | 
            +
                        // promise chain paralleling the asserter chain, we can use it to communicate such changes.
         | 
| 310 | 
            +
                        return assertion._obj;
         | 
| 323 311 | 
             
                    });
         | 
| 324 312 |  | 
| 325 | 
            -
                     | 
| 326 | 
            -
             | 
| 327 | 
            -
                    };
         | 
| 328 | 
            -
             | 
| 329 | 
            -
                    assert.isRejected = function (promise, toTestAgainst, message) {
         | 
| 330 | 
            -
                        if (typeof toTestAgainst === "string") {
         | 
| 331 | 
            -
                            message = toTestAgainst;
         | 
| 332 | 
            -
                            toTestAgainst = undefined;
         | 
| 333 | 
            -
                        }
         | 
| 313 | 
            +
                    module.exports.transferPromiseness(assertion, derivedPromise);
         | 
| 314 | 
            +
                }
         | 
| 334 315 |  | 
| 335 | 
            -
             | 
| 336 | 
            -
             | 
| 337 | 
            -
             | 
| 316 | 
            +
                ///////
         | 
| 317 | 
            +
                // Now use the `Assertion` framework to build an `assert` interface.
         | 
| 318 | 
            +
                var originalAssertMethods = Object.getOwnPropertyNames(assert).filter(function (propName) {
         | 
| 319 | 
            +
                    return typeof assert[propName] === "function";
         | 
| 320 | 
            +
                });
         | 
| 338 321 |  | 
| 339 | 
            -
             | 
| 340 | 
            -
             | 
| 341 | 
            -
             | 
| 322 | 
            +
                assert.isFulfilled = function (promise, message) {
         | 
| 323 | 
            +
                    return (new Assertion(promise, message)).to.be.fulfilled;
         | 
| 324 | 
            +
                };
         | 
| 342 325 |  | 
| 343 | 
            -
             | 
| 344 | 
            -
             | 
| 345 | 
            -
                     | 
| 326 | 
            +
                assert.isRejected = function (promise, errorLike, errMsgMatcher, message) {
         | 
| 327 | 
            +
                    var assertion = (new Assertion(promise, message));
         | 
| 328 | 
            +
                    return assertion.to.be.rejectedWith(errorLike, errMsgMatcher, message);
         | 
| 329 | 
            +
                };
         | 
| 346 330 |  | 
| 347 | 
            -
             | 
| 348 | 
            -
                     | 
| 349 | 
            -
             | 
| 350 | 
            -
                            var otherArgs = Array.prototype.slice.call(arguments, 1);
         | 
| 331 | 
            +
                assert.becomes = function (promise, value, message) {
         | 
| 332 | 
            +
                    return assert.eventually.deepEqual(promise, value, message);
         | 
| 333 | 
            +
                };
         | 
| 351 334 |  | 
| 352 | 
            -
             | 
| 353 | 
            -
             | 
| 354 | 
            -
             | 
| 355 | 
            -
                                customRejectionHandler = function (reason) {
         | 
| 356 | 
            -
                                    throw new chai.AssertionError(message + "\n\nOriginal reason: " + utils.inspect(reason));
         | 
| 357 | 
            -
                                };
         | 
| 358 | 
            -
                            }
         | 
| 335 | 
            +
                assert.doesNotBecome = function (promise, value, message) {
         | 
| 336 | 
            +
                    return assert.eventually.notDeepEqual(promise, value, message);
         | 
| 337 | 
            +
                };
         | 
| 359 338 |  | 
| 360 | 
            -
             | 
| 361 | 
            -
             | 
| 362 | 
            -
             | 
| 363 | 
            -
             | 
| 364 | 
            -
                                customRejectionHandler
         | 
| 365 | 
            -
                            );
         | 
| 339 | 
            +
                assert.eventually = {};
         | 
| 340 | 
            +
                originalAssertMethods.forEach(function (assertMethodName) {
         | 
| 341 | 
            +
                    assert.eventually[assertMethodName] = function (promise) {
         | 
| 342 | 
            +
                        var otherArgs = Array.prototype.slice.call(arguments, 1);
         | 
| 366 343 |  | 
| 367 | 
            -
             | 
| 368 | 
            -
             | 
| 344 | 
            +
                        var customRejectionHandler;
         | 
| 345 | 
            +
                        var message = arguments[assert[assertMethodName].length - 1];
         | 
| 346 | 
            +
                        if (typeof message === "string") {
         | 
| 347 | 
            +
                            customRejectionHandler = function (reason) {
         | 
| 348 | 
            +
                                throw new chai.AssertionError(message + "\n\nOriginal reason: " + utils.inspect(reason));
         | 
| 369 349 | 
             
                            };
         | 
| 350 | 
            +
                        }
         | 
| 351 | 
            +
             | 
| 352 | 
            +
                        var returnedPromise = promise.then(
         | 
| 353 | 
            +
                            function (fulfillmentValue) {
         | 
| 354 | 
            +
                                return assert[assertMethodName].apply(assert, [fulfillmentValue].concat(otherArgs));
         | 
| 355 | 
            +
                            },
         | 
| 356 | 
            +
                            customRejectionHandler
         | 
| 357 | 
            +
                        );
         | 
| 370 358 |  | 
| 371 | 
            -
             | 
| 359 | 
            +
                        returnedPromise.notify = function (done) {
         | 
| 360 | 
            +
                            doNotify(returnedPromise, done);
         | 
| 372 361 | 
             
                        };
         | 
| 373 | 
            -
             | 
| 374 | 
            -
             | 
| 375 | 
            -
            } | 
| 362 | 
            +
             | 
| 363 | 
            +
                        return returnedPromise;
         | 
| 364 | 
            +
                    };
         | 
| 365 | 
            +
                });
         | 
| 366 | 
            +
            };
         | 
| 367 | 
            +
             | 
| 368 | 
            +
            module.exports.transferPromiseness = function (assertion, promise) {
         | 
| 369 | 
            +
                assertion.then = promise.then.bind(promise);
         | 
| 370 | 
            +
            };
         | 
| 371 | 
            +
             | 
| 372 | 
            +
            module.exports.transformAsserterArgs = function (values) {
         | 
| 373 | 
            +
                return values;
         | 
| 374 | 
            +
            };
         | 
    
        package/package.json
    CHANGED
    
    | @@ -11,7 +11,7 @@ | |
| 11 11 | 
             
                "promises",
         | 
| 12 12 | 
             
                "promises-aplus"
         | 
| 13 13 | 
             
              ],
         | 
| 14 | 
            -
              "version": " | 
| 14 | 
            +
              "version": "6.0.0",
         | 
| 15 15 | 
             
              "author": "Domenic Denicola <d@domenic.me> (https://domenic.me)",
         | 
| 16 16 | 
             
              "license": "WTFPL",
         | 
| 17 17 | 
             
              "repository": "domenic/chai-as-promised",
         | 
| @@ -23,21 +23,21 @@ | |
| 23 23 | 
             
                "test": "npm run test-plugin && npm run test-intercompatibility",
         | 
| 24 24 | 
             
                "test-plugin": "mocha",
         | 
| 25 25 | 
             
                "test-intercompatibility": "mocha test-intercompatibility --opts test-intercompatibility/mocha.opts",
         | 
| 26 | 
            -
                "test-browser-jquery": "coffee ./test/browser/runner.coffee jquery",
         | 
| 27 | 
            -
                "test-browser-q": "coffee ./test/browser/runner.coffee q",
         | 
| 28 | 
            -
                "test-browser-when": "coffee ./test/browser/runner.coffee when",
         | 
| 29 26 | 
             
                "lint": "jshint ./lib",
         | 
| 30 27 | 
             
                "cover": "istanbul cover node_modules/mocha/bin/_mocha && opener ./coverage/lcov-report/lib/chai-as-promised.js.html"
         | 
| 31 28 | 
             
              },
         | 
| 29 | 
            +
              "dependencies": {
         | 
| 30 | 
            +
                "check-error": "^1.0.2"
         | 
| 31 | 
            +
              },
         | 
| 32 32 | 
             
              "peerDependencies": {
         | 
| 33 33 | 
             
                "chai": ">= 2.1.2 < 4"
         | 
| 34 34 | 
             
              },
         | 
| 35 35 | 
             
              "devDependencies": {
         | 
| 36 36 | 
             
                "chai": "^3.0.0",
         | 
| 37 37 | 
             
                "coffee-script": "1.10.0",
         | 
| 38 | 
            -
                "istanbul": "0.4.1",
         | 
| 39 38 | 
             
                "ecstatic": "^1.3.1",
         | 
| 40 39 | 
             
                "glob": "^6.0.1",
         | 
| 40 | 
            +
                "istanbul": "0.4.1",
         | 
| 41 41 | 
             
                "jshint": "^2.8.0",
         | 
| 42 42 | 
             
                "mocha": "^2.3.4",
         | 
| 43 43 | 
             
                "opener": "^1.4.1",
         |