Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

smaller, more configurable pretty-printing of objects #196

Closed
wants to merge 2 commits into from

3 participants

@maxbrunsfeld

This includes two changes to the pretty printer:

  1. There's a new constant jasmine.MAX_PRETTY_PRINT_DEPTH, which controls how deeply the pretty-printer will recurse when stringifying an object. The depth was previously hard-coded to 40. When the limit is reached, rather than throwing an exception, the pretty printer will simply emit Object or Array. This allows you to set the recursion depth lower without breaking your tests. Personally I find that after a few levels of depth, the readability of the output decreases, so I would set MAX_PRETTY_PRINT_DEPTH to 4 or 5. Other people might want to leave it at 40 to see the entire structure.

  2. When stringifying an object, the pretty-printer will now skip over its inherited properties. This one might be controversial. We hacked it in on our project because when one of our Backbone-derived model objects got printed out, the number of prototypal methods that was included made it hard to discern much about the actual object. I think the fact that the pretty-printer currently includes these properties is responsible for most of the too-long-to-read messages that jasmine produces.

Curious what you guys think of number 2.

maxbrunsfeld added some commits
@maxbrunsfeld maxbrunsfeld When pretty-printing objects, don't include inherited properties.
When making assertions about complex objects, Jasmine's
failure message are sometimes gigantic and difficult
to read because the string representation of an object
contains all of the methods and properties in its
prototype chain. This commit causes the pretty printer
to only display on object's own properties.
00aa607
@maxbrunsfeld maxbrunsfeld Allow users to set the pretty-printer's recursion depth
Currently, jasmine's pretty printer traverses objects
to 40 levels of nesting. If an object is more deeply
nested than that, an exception is thrown. I find that
after a few levels of nesting, the output becomes
difficult to read. The process of serializing such
deep objects also sometimes crashes the browser or
causes a 'slow script' warning.

This commit exposes a 'MAX_PRETTY_PRINT_DEPTH' option.
It also causes the pretty printer to skip over
parts of an object that are nested to deeply by simply
printing out 'Object' or 'Array', rather than throwing
an exception.
1136535
@ragaskar
Owner

This seems fine to me, including #2. I have no real opinion on pretty printing depth because I've rarely seen a need for more than one or two levels to verify what the problem is with your test. We'd probably also want to knock down the default depth as part of this, 40 seems too large. Story here: https://www.pivotaltracker.com/story/show/29584887

@wolframkriesing

is this going to be merged or is there an alternative?

@maxbrunsfeld

I rebased these two commits onto master: #290. I'll close this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 5, 2012
  1. @maxbrunsfeld

    When pretty-printing objects, don't include inherited properties.

    maxbrunsfeld authored
    When making assertions about complex objects, Jasmine's
    failure message are sometimes gigantic and difficult
    to read because the string representation of an object
    contains all of the methods and properties in its
    prototype chain. This commit causes the pretty printer
    to only display on object's own properties.
  2. @maxbrunsfeld

    Allow users to set the pretty-printer's recursion depth

    maxbrunsfeld authored
    Currently, jasmine's pretty printer traverses objects
    to 40 levels of nesting. If an object is more deeply
    nested than that, an exception is thrown. I find that
    after a few levels of nesting, the output becomes
    difficult to read. The process of serializing such
    deep objects also sometimes crashes the browser or
    causes a 'slow script' warning.
    
    This commit exposes a 'MAX_PRETTY_PRINT_DEPTH' option.
    It also causes the pretty printer to skip over
    parts of an object that are nested to deeply by simply
    printing out 'Object' or 'Array', rather than throwing
    an exception.
This page is out of date. Refresh to see the latest.
View
30 spec/core/PrettyPrintSpec.js
@@ -32,6 +32,36 @@ describe("jasmine.pp", function () {
}, bar: [1, 2, 3]})).toEqual("{ foo : Function, bar : [ 1, 2, 3 ] }");
});
+ it("should not include inherited properties when stringifying an object", function() {
+ var SomeClass = function() {};
+ SomeClass.prototype.foo = "inherited foo";
+ var instance = new SomeClass();
+ instance.bar = "my own bar";
+ expect(jasmine.pp(instance)).toEqual("{ bar : 'my own bar' }");
+ });
+
+ it("should not recurse objects and arrays more deeply than jasmine.MAX_PRETTY_PRINT_DEPTH", function() {
+ var originalMaxDepth = jasmine.MAX_PRETTY_PRINT_DEPTH;
+ var nestedObject = { level1: { level2: { level3: { level4: "leaf" } } } };
+ var nestedArray = [1, [2, [3, [4, "leaf"]]]];
+
+ try {
+ jasmine.MAX_PRETTY_PRINT_DEPTH = 2;
+ expect(jasmine.pp(nestedObject)).toEqual("{ level1 : { level2 : Object } }");
+ expect(jasmine.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");
+
+ jasmine.MAX_PRETTY_PRINT_DEPTH = 3;
+ expect(jasmine.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : Object } } }");
+ expect(jasmine.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");
+
+ jasmine.MAX_PRETTY_PRINT_DEPTH = 4;
+ expect(jasmine.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : { level4 : 'leaf' } } } }");
+ expect(jasmine.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
+ } finally {
+ jasmine.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
+ }
+ });
+
it("should stringify RegExp objects properly", function() {
expect(jasmine.pp(/x|y|z/)).toEqual("/x|y|z/");
});
View
15 src/core/PrettyPrinter.js
@@ -11,10 +11,6 @@ jasmine.PrettyPrinter = function() {
* @param value
*/
jasmine.PrettyPrinter.prototype.format = function(value) {
- if (this.ppNestLevel_ > 40) {
- throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');
- }
-
this.ppNestLevel_++;
try {
if (value === jasmine.undefined) {
@@ -57,6 +53,7 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
for (var property in obj) {
+ if (!obj.hasOwnProperty(property)) continue;
if (property == '__Jasmine_been_here_before__') continue;
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
obj.__lookupGetter__(property) !== null) : false);
@@ -84,6 +81,11 @@ jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
};
jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
+ if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
+ this.append("Array");
+ return;
+ }
+
this.append('[ ');
for (var i = 0; i < array.length; i++) {
if (i > 0) {
@@ -95,6 +97,11 @@ jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
};
jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
+ if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
+ this.append("Object");
+ return;
+ }
+
var self = this;
this.append('{ ');
var first = true;
View
5 src/core/base.js
@@ -35,6 +35,11 @@ jasmine.VERBOSE = false;
jasmine.DEFAULT_UPDATE_INTERVAL = 250;
/**
+ * Maximum levels of nesting that will be included when an object is pretty-printed
+ */
+jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
+
+/**
* Default timeout interval in milliseconds for waitsFor() blocks.
*/
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
Something went wrong with that request. Please try again.