11

I want to print JSON.stringify()'d objects to the console, for context as part of a Mocha test suite output.

As the tests indent, I'd like the object log lines to be indented far enough rightwards (say, 3-4 tab spaces) that they are recognisably in the right describe() group.

How could I achieve this with something like console.log or process.stdout.write?

yellow-saint
  • 884
  • 2
  • 13
  • 37
  • Look at the extra parameters of `JSON.stringify` on the [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). – MinusFour Sep 12 '15 at 16:15
  • 1
    @MinusFour That leaves the initial curly brackets at column 0, and creates spaces at all depths of the object. I want a normal `JSON.stringify(obj,null,2)` output, all shifted right by three tabspaces. – yellow-saint Sep 12 '15 at 16:53
  • 1
    Then you want to shift the whole string by 3 tabspaces? – MinusFour Sep 12 '15 at 16:57
  • @MinusFour - yes. Every line needs to shift. – yellow-saint Sep 12 '15 at 16:58

3 Answers3

14

If just used for console.log you might want to look up for groups, check this on your console:

var obj = {
  a : 1,
  b : 2,
  c: 3
  }

console.log('Non-tabbed');
console.group();
console.log(JSON.stringify(obj, null, 2));
console.groupEnd();
console.log('Back to non-tabbed');

Works fine on current browsers and latest node. There's also a package on npm that might just work for that if you are working with older node versions.

node-console-group

This shifts the whole JSON string by 3 spaces. It breaks the JSON string by new lines, then adds on each line 3 spaces to a new string which will hold every line shifted.

var results = document.getElementById('results');
var obj = {
    a: 5,
    b: 3,
    c: 4
};

var string = JSON.stringify(obj, null, 2);

var stringShifted = '';
string.split('\n').forEach(function(line){
    stringShifted += '   ' + line + '\n';
});
console.log(string);
console.log(stringShifted);

results.innerHTML = 'Before : \n' + string;
results.innerHTML += '\n\nAfter : \n' + stringShifted;
<pre id="results"></pre>
MinusFour
  • 13,913
  • 3
  • 30
  • 39
0

You can add a short reg-ex replace on the JSON.stringify output to get the effect that you're after.

var myObject = _buildAnObject();   

it("Should log my entire JSON.stringify indented", function(){
   console.log("My log message: \n\t" 
        + JSON.stringify(myObject, null, 2).replace(/\n\r?/g, '\n\t'));
   assert(true);
});

I've put a working mocha example on codepen.io.

Ryan Kimber
  • 495
  • 1
  • 6
  • 14
-1

under nodejs you can try util.inspect(obj, {depth:10, colors:true ...}) i used it under mocha tested to indent logs

const log = (...args:unknown[])=>{
    setTimeout(()=>{
        let indent = "\t";
        args = args.map(a=>util.inspect(a, {colors:true, depth:10}).replace(/^\x1B\[32m['"`]/ig, '\x1B[32m').replace(/['"`]\x1B\[39m$/ig, '\x1B[39m').replace(/\n/g, `\n${indent} `))
        console.log.call(console, indent, ...args);
    })
}
let user = {
    name:"surinder singh",
    age:38,
    hobbies:[{
        name:"Something interesting",
        from:"birth"
    },{
        name:"Electronic DIY",
        from:"from ~primary"
    },{
        name:"Coding",
        from:"after school"
    }]
}
let args = ["a string 1234", 123 , {xyz:"xyz", num:123, arr:["xxx", 123, {345:"xxx"}, user], bool:true}];

console.log( ...args );
log( ...args  )

enter image description here

surinder singh
  • 1,463
  • 13
  • 12
  • According to [the docs](https://nodejs.org/en/knowledge/getting-started/how-to-use-util-inspect/), the depth argument doesn't do what you think it does: > *"The depth argument is the __number of levels deep into a nested object to recurse__ - it defaults to 2. Setting it to null will cause it to recurse 'all the way', showing every level."* – yellow-saint Aug 16 '22 at 12:09
  • i am indenting using `.replace(/\n/g, '\n${indent} ')` not with depth option – surinder singh Aug 29 '22 at 12:29