Example of Monkey Patching Chai.js to display expected / actual objects using their .toString() methods

refrenced as part of answering http://stackoverflow.com/questions/26980779/how-can-i-get-chai-to-show-actual-and-expected-values-using-tostring

by humbletim

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/1.10.0/chai.js"></script>
<div id="mocha"></div>

CSS

pre.error {
    max-height: 3em !important;
}
h2 { color: blue }
.failures:before { content:'(pseudo)' }

JavaScript

// set threshold low for demo purposes
chai.config.truncateThreshold = 1;

MonkeyPatchChai = function () {
    // http://en.wikipedia.org/wiki/Monkey_patch
    chai.use(function (a, utils) {
        // make a backup of original (for use in last demo)
        utils._objDisplay = utils.objDisplay;
        
        // "re-link" utils.getMessage so that it finds objDisplay via utils scope chain
        (function () {
            "use riot gear";
            with(utils) { getMessage = eval("1," + getMessage); }
        })();

        // override utils.objDisplay
        utils.objDisplay = function (obj) {
            return obj + ''; // nil-safe obj.toString()
        };
    });
};

expect = chai.expect;
mocha.setup("bdd");

before(function () {
    A = [1,2,3,4,5,6,7,8,9];
    B = [1,2,3,4,5,6,7,8,9];
    B[5] *= -1;
});

describe("stock Chai.utils.objDisplay", function () {
    it("should display Objects truncated", function () {
        expect(A).to.deep.equal(B);
    });
});

describe("monkeypatched Chai.utils.objDisplay", function () {
    before(MonkeyPatchChai);
    it("should display Objects via natural toString()", function () {
        expect(A).to.deep.equal(B);
    });
});

describe("custom .toString and patched Chai.utils.objDisplay", function () {
    before(function() {
        // just to demo; probably you'd do this on your custom object's .prototype
        B.toString = A.toString = function() { return "|"+this.join(",")+"|"; };
    });
    it("should display Objects via custom toString()", function () {
        expect(A).to.deep.equal(B);
    });
});

// example generalization -- a new chai config option, which could be configured/toggled at the test suite level
chai.config.inspect = function(obj) { 
    if(obj instanceof Array)
        return "Array having sum "+
            obj.reduce(function(a,b) { return a+b; }, 0);
    return obj; // any other type just passes through 
};

function MonkeyPatchChaiInspect() {
    chai.use(function(_, utils) {
  ...