lib/promiseclass.js
function chaiSupportChainPromise(chai, utils){
    function copyChainPromise(promise, assertion){
        let protoPromise = Object.getPrototypeOf(promise);
        let protoNames = Object.getOwnPropertyNames(protoPromise);
        let protoAssertion = Object.getPrototypeOf(assertion);
        protoNames.forEach(function(protoName){
            if(protoName !== 'constructor' && !protoAssertion[protoName]){
                assertion[protoName] = promise[protoName].bind(promise);
            }
        });
    }
    function doAsserterAsync(asserter, assertion, args){
        let self = utils.flag(assertion, "object");
        if(self && self.then && typeof self.then === "function"){
            let promise = self.then(function(value){
                assertion._obj = value;
                asserter.apply(assertion, args);
                return value;
            }, function(error){
                assertion._obj = new Error(error);
                asserter.apply(assertion, args);
            });
            copyChainPromise(promise, assertion);
        }
        else{
            return asserter.apply(assertion, args);
        }
    }
    let Assertion = chai.Assertion;
    let propertyNames = Object.getOwnPropertyNames(Assertion.prototype);

    let propertyDescs = {};
    propertyNames.forEach(function (name) {
        propertyDescs[name] = Object.getOwnPropertyDescriptor(Assertion.prototype, name);
    });

    let methodNames = propertyNames.filter(function (name) {
        return name !== "assert" && typeof propertyDescs[name].value === "function";
    });

    methodNames.forEach(function (methodName) {
        Assertion.overwriteMethod(methodName, function (originalMethod) {
            return function () {
                doAsserterAsync(originalMethod, this, arguments);
            };
        });
    });

    let getterNames = propertyNames.filter(function (name) {
        return name !== "_obj" && typeof propertyDescs[name].get === "function";
    });

    getterNames.forEach(function (getterName) {
        let isChainableMethod = Assertion.prototype.__methods.hasOwnProperty(getterName);
        if (isChainableMethod) {
            Assertion.overwriteChainableMethod(
                getterName,
                function (originalMethod) {
                    return function() {
                        doAsserterAsync(originalMethod, this, arguments);
                    };
                },
                function (originalGetter) {
                    return function() {
                        doAsserterAsync(originalGetter, this);
                    };
                }
            );
        } else {
            Assertion.overwriteProperty(getterName, function (originalGetter) {
                return function () {
                    doAsserterAsync(originalGetter, this);
                };
            });
        }
    });
}
function chaiSupportChainPromise(chai, utils){
    function copyChainPromise(promise, assertion){
        let protoPromise = Object.getPrototypeOf(promise);
        let protoNames = Object.getOwnPropertyNames(protoPromise);
        let protoAssertion = Object.getPrototypeOf(assertion);
        protoNames.forEach(function(protoName){
            if(protoName !== 'constructor' && !protoAssertion[protoName]){
                assertion[protoName] = promise[protoName].bind(promise);
            }
        });
    }
    function doAsserterAsync(asserter, assertion, args){
        let self = utils.flag(assertion, "object");
        if(self && self.then && typeof self.then === "function"){
            let promise = self.then(function(value){
                assertion._obj = value;
                asserter.apply(assertion, args);
                return value;
            }, function(error){
                assertion._obj = new Error(error);
                asserter.apply(assertion, args);
            });
            copyChainPromise(promise, assertion);
        }
        else{
            return asserter.apply(assertion, args);
        }
    }
    let Assertion = chai.Assertion;
    let propertyNames = Object.getOwnPropertyNames(Assertion.prototype);

    let propertyDescs = {};
    propertyNames.forEach(function (name) {
        propertyDescs[name] = Object.getOwnPropertyDescriptor(Assertion.prototype, name);
    });

    let methodNames = propertyNames.filter(function (name) {
        return name !== "assert" && typeof propertyDescs[name].value === "function";
    });

    methodNames.forEach(function (methodName) {
        Assertion.overwriteMethod(methodName, function (originalMethod) {
            return function () {
                doAsserterAsync(originalMethod, this, arguments);
            };
        });
    });

    let getterNames = propertyNames.filter(function (name) {
        return name !== "_obj" && typeof propertyDescs[name].get === "function";
    });

    getterNames.forEach(function (getterName) {
        let isChainableMethod = Assertion.prototype.__methods.hasOwnProperty(getterName);
        if (isChainableMethod) {
            Assertion.overwriteChainableMethod(
                getterName,
                function (originalMethod) {
                    return function() {
                        doAsserterAsync(originalMethod, this, arguments);
                    };
                },
                function (originalGetter) {
                    return function() {
                        doAsserterAsync(originalGetter, this);
                    };
                }
            );
        } else {
            Assertion.overwriteProperty(getterName, function (originalGetter) {
                return function () {
                    doAsserterAsync(originalGetter, this);
                };
            });
        }
    });
}
function chaiSupportChainPromise ( chai , utils ) { function copyChainPromise ( promise , assertion ) { let protoPromise = Object . getPrototypeOf ( promise ) ; let protoNames = Object . getOwnPropertyNames ( protoPromise ) ; let protoAssertion = Object . getPrototypeOf ( assertion ) ; protoNames . forEach ( function ( protoName ) { if ( protoName !== 'constructor' && ! protoAssertion [ protoName ] ) { assertion [ protoName ] = promise [ protoName ] . bind ( promise ) ; } } ) ; } function doAsserterAsync ( asserter , assertion , args ) { let self = utils . flag ( assertion , "object" ) ; if ( self && self . then && typeof self . then === "function" ) { let promise = self . then ( function ( value ) { assertion . _obj = value ; asserter . apply ( assertion , args ) ; return value ; } , function ( error ) { assertion . _obj = new Error ( error ) ; asserter . apply ( assertion , args ) ; } ) ; copyChainPromise ( promise , assertion ) ; } else { return asserter . apply ( assertion , args ) ; } } let Assertion = chai . Assertion ; let propertyNames = Object . getOwnPropertyNames ( Assertion . prototype ) ; let propertyDescs = { } ; propertyNames . forEach ( function ( name ) { propertyDescs [ name ] = Object . getOwnPropertyDescriptor ( Assertion . prototype , name ) ; } ) ; let methodNames = propertyNames . filter ( function ( name ) { return name !== "assert" && typeof propertyDescs [ name ] . value === "function" ; } ) ; methodNames . forEach ( function ( methodName ) { Assertion . overwriteMethod ( methodName , function ( originalMethod ) { return function ( ) { doAsserterAsync ( originalMethod , this , arguments ) ; } ; } ) ; } ) ; let getterNames = propertyNames . filter ( function ( name ) { return name !== "_obj" && typeof propertyDescs [ name ] . get === "function" ; } ) ; getterNames . forEach ( function ( getterName ) { let isChainableMethod = Assertion . prototype . __methods . hasOwnProperty ( getterName ) ; if ( isChainableMethod ) { Assertion . overwriteChainableMethod ( getterName , function ( originalMethod ) { return function ( ) { doAsserterAsync ( originalMethod , this , arguments ) ; } ; } , function ( originalGetter ) { return function ( ) { doAsserterAsync ( originalGetter , this ) ; } ; } ) ; } else { Assertion . overwriteProperty ( getterName , function ( originalGetter ) { return function ( ) { doAsserterAsync ( originalGetter , this ) ; } ; } ) ; } } ) ; }
support ChainPromise for chai
support ChainPromise for chai